Hi everyone,
I have an energy system with an offset converter and a generic storage.
The converter produces hydrogen and must meet a demand. I specify the production of the converter on the basis of a previous optimisation by using a custom constraint. It is ensured that the production always covers the demand. Surplus production should be stored in the storage tank.
If the converter produces more than is demanded I get the error that my problem is infeasible or unbounded.
Does anyone have an idea what could be the problem?
That’s my energysystem. For the example I only optimize one timestep. But you can extend the time horizon if you like.
electricity_flow_ely1_1 = 15
storage_content_h2_storage = 0
n=0
#Hier wird der Startzeitpunkt in jeder Iteration um eine Stunde nach hinten verschoben - passend zu den Listen
start_time = dt.datetime(2019, 1, 1, 0, 0) + dt.timedelta(hours=n)
#definition of time index
datetime_index = solph.create_time_index(year=2019, number=1, start=start_time)
es3 = solph.EnergySystem(timeindex=datetime_index, infer_last_interval=False)
#Definition Bus-Components
b_el = solph.Bus("electricity bus")
b_h2 = solph.Bus("hydrogen bus")
b_heat = solph.Bus("heat bus")
b_o2 = solph.Bus("oxygen bus")
#b_h2_output = solph.Bus("hydrogen output bus")
##### Definition der Komponenten #####
#electricity source for basic hydrogen demand
source_el = solph.components.Source(
"electricity import",
outputs={
b_el: solph.Flow(
)
}
)
#Sink for fix hydrogen demand via contract
sink_h2_demand = solph.components.Sink(
"hydrogen demand",
inputs={
b_h2: solph.Flow(
fix=5,
nominal_value=1,
variable_costs=c_h2_virtual
)
}
)
#sink for byproduct heat
sink_heat = solph.components.Sink(
"heat export",
inputs={
b_heat: solph.Flow(
variable_costs=c_heat
)
}
)
#sink for byproduct oxygen
sink_o2 = solph.components.Sink(
"oxygen export",
inputs={
b_o2: solph.Flow(
variable_costs=c_oxygen
)
}
)
#### Electrolyzer hydrogen market ####
#firt part electrolyzer to cover hydrogen demand/production
electrolyzer1_1 = solph.components.OffsetConverter(
label='electrolyzer market 1',
inputs={
b_el: solph.Flow(
nominal_value=P_in_max,
nonconvex=solph.NonConvex(),
min=P_in_min / P_in_max,
)
},
outputs={
b_heat: solph.Flow(),
b_h2: solph.Flow(),
b_o2: solph.Flow(),
},
conversion_factors={
b_heat: slope_heat,
b_h2: slope_h2,
b_o2: slope_o2
},
normed_offsets={
b_heat: offset_heat,
b_h2: offset_h2,
b_o2: offset_o2
}
)
#hydrogen storage
h2_storage = solph.components.GenericStorage(
label="hydrogen storage",
nominal_storage_capacity = hydrogen_storage_capacity,
inputs={
b_h2: solph.Flow(
nominal_value=hydrogen_storage_input_flow,
variable_costs=hydrogen_storage_variable_costs,
nonconvex=solph.NonConvex()
)
},
outputs={
b_h2:solph.Flow(
nominal_value=hydrogen_storage_output_flow
)
},
loss_rate=hydrogen_storage_loss_rate,
initial_storage_level=storage_content_h2_storage,
)
es3.add(b_el, b_h2, b_heat, b_o2,
source_el, sink_h2_demand, sink_heat, sink_o2, electrolyzer1_1, h2_storage
)
om3 = solph.Model(es3)
myblock3 = po.Block()
om3.add_component("MyBlock3", myblock3)
def flow_ely1_1(m,t):
expr = om3.flow[b_el, electrolyzer1_1, t] == electricity_flow_ely1_1
return expr
myblock3.flow_ely1_1 = po.Constraint(om3.TIMESTEPS, rule=flow_ely1_1)
#lösen des Optimierungsproblems
om3.solve("gurobi")
results3 = solph.views.convert_keys_to_strings(om3.results(), keep_none_type=True)
Here are the basic variables and other stuff of the Code:
from oemof import solph
import pandas as pd
import numpy as np
import pyomo.environ as po
import random
import datetime as dt
##################### einzugebende Parameter #####################
num_tsteps = 24 #Anzahl der Zeitschritte
c_h2_virtual=-10
c_heat=0
c_oxygen=0
#Daten Teillastverahlten
eta_h2_min = 0.60 #efficiency at P_in_min
eta_h2_max = 0.50 #efficiency at P_in_max
P_in_min = 2
P_in_max = 20
#slope und offset for part-load behavior hydrogen, heat, oxygen
slope_h2, offset_h2 = solph.components._offset_converter.slope_offset_from_nonconvex_input(P_in_max, P_in_min, eta_at_max=0.5, eta_at_min=0.6)
slope_heat, offset_heat = solph.components._offset_converter.slope_offset_from_nonconvex_input(P_in_max, P_in_min, eta_at_max=0.4, eta_at_min=0.3)
slope_o2, offset_o2 = solph.components._offset_converter.slope_offset_from_nonconvex_input(P_in_max, P_in_min, eta_at_max=0.2, eta_at_min=0.1)
#sonstige Variablen
hydrogen_storage_capacity = 150
hydrogen_storage_input_flow = 50
hydrogen_storage_output_flow = 50
hydrogen_storage_variable_costs = 0
hydrogen_storage_loss_rate = 0.002
hydrogen_storage_initial_storage_level = 0