Hello,
I am trying to understand oemof with one small unit commitment example, which I have implemented in pyomo a) as an abstract model and b) using blocks. There are only three time steps and three plants with respective economic dispatch and unit commitment constraints as well as some costs.
The following data is stored in a subfolder called input as csv files:
**********demand.csv ***********
T,Demand
1,150
2,500
3,400
************plant_params csv **********
J,Pmax,Pmin,RU,RD,FC,VC,SU,SD
1,370,50,200,300,200,4,800,20
2,200,80,100,150,280,5,720,12
3,140,40,100,100,240,6,200,40
The demand is self explaining. The parameters are in the column order: maximum/ minimum power output, ramp up/ down gradient per time step, fixed cost if in operation, variable cost, start up/ shut down cost.
At first I got an error, because I passed the OffsetTransformer coefficients as a dict, as it is presented in the class documentation. Then I realized that it should be a nested list according to the example included in the tests. Are these two different objects, which I don’t see so far, or is there maybe an inconsistency within the docs? Now I get the following:
WARNING:pyomo.core:Constant objective detected, replacing with a placeholder to prevent solver failure.
ERROR:root:Optimization failed with status ok and terminal condition infeasible
This is the code I am using for oemof:
import pandas as pd
from oemof.tools import helpers
import oemof.outputlib as outputlib
import oemof.solph as solph
demand = pd.read_csv('input/demand.csv')
plants = pd.read_csv('input/plant_params.csv', index_col=0)
solver = 'cbc'
energysystem = solph.EnergySystem(timeindex=demand.index)
bfuel = solph.Bus(label="fuel", variable_costs=1)
bel = solph.Bus(label="electricity")
energysystem.add(bfuel, bel)
energysystem.add(solph.Source(label='fuel_source',
outputs={bfuel: solph.Flow(nominal_value=10e3)}))
fixed_param = lambda val: [val for _ in demand.index]
for p in plants.index:
plant = plants.loc[p]
transf = solph.custom.OffsetTransformer(
label="plant{}".format(plant.name),
inputs={bfuel: solph.Flow(
nominal_value=plant['Pmax'],
min=fixed_param(plant['Pmax'] / plant['Pmin']),
positive_gradient={'ub': plant['RU'], 'costs': 0},
negative_gradient={'ub': plant['RD'], 'costs': 0},
startup_costs=plant['SU'],
shutdown_costs=plant['SD'],
nonconvex=solph.NonConvex())},
outputs={bel: solph.Flow()},
coefficients=[fixed_param(plant['FC']),
fixed_param(plant['VC'])
])
energysystem.add(transf)
energysystem.add(solph.Sink(label='demand', inputs={bel: solph.Flow(
actual_value=demand['Demand'], fixed=True, nominal_value=1)}))
model = solph.Model(energysystem)
model.solve(solver=solver)
I would be very happy, if anyone has an idea, what I do wrong.
Best Philipp