Reputation: 11379
I am writing an energy optimization model using Pyomo. In this model I have a constraint which updates the charge level of an energy storage at every time-step using the charge level in the previous time-step (simplified equation):
Storage_level[t] = Storage_level[t-1] + Charge [t] - Discharge [t]
And there is an additional constraint for the initial period:
Storage_level[1] = 0
When I run the problem, I don't get any useful result and the output window just displays the constraint bounds, such as:
ev_soc_max : Size=24
Key : Lower : Body : Upper
1 : None : None : 0.0
2 : None : None : 0.0
3 : None : None : 0.0
4 : None : None : 0.0
5 : None : None : 0.0
...
and I also get this error for some variables:
ERROR: evaluating object as numeric value: p_bat_ch[1]
(object: <class 'pyomo.core.base.var._GeneralVarData'>)
No value for uninitialized NumericValue object p_bat_ch[1]
I suspect that the problem is related to the definition of the storage constraints.
This is how I coded it in Pyomo (I came to this result by combining different examples which I found here and there on the internet):
def bat_soc_ini_rule(model, t):
if t == 1:
return model.e_bat_t[t] == 0.
else:
return Constraint.Skip
model.bat_soc_ini = Constraint(model.T, rule = bat_soc_ini_rule)
def bat_soc_rule(model, t):
if t >= 2:
return model.e_bat_t[t] == model.eta_bat_cal * model.e_bat_t[t-1] + model.eta_bat_ch * model.p_bat_ch[t] - model.eta_bat_dis**-1 * model.p_bat_dis[t]
else:
return Constraint.Skip
model.bat_soc = Constraint(model.T, rule = bat_soc_rule)
I should also state that I declared the model.T
set using model.T = RangeSet(24)
and the variables are declared as follows: model.e_bat_t = Var(model.T, within = NonNegativeReals)
One last point: I am using GLPK as a solver.
My questions are:
How should I declare a constraint which calls a previous member of the set? Am I doing it right?
How should I set a constraint on only part of a set (e.g. for the initialization constraint)?
Am I right in thinking that the error comes from the incorrect definition of this constraint? If not, do you have any idea where the problem could come from?
Upvotes: 1
Views: 1372
Reputation: 1568
Well, I am working with urbs atm and following code comes from it.
This is the constraint rule you are looking for storage[t] = storage[t-1] + in - out
# storage content in timestep [t] == storage content[t-1] * (1-discharge)
# + newly stored energy * input efficiency
# - retrieved energy / output efficiency
def def_storage_state_rule(m, t, sit, sto, com):
return (m.e_sto_con[t, sit, sto, com] ==
m.e_sto_con[t-1, sit, sto, com] *
(1 - m.storage_dict['discharge'][(sit, sto, com)]) ** m.dt.value +
m.e_sto_in[t, sit, sto, com] *
m.storage_dict['eff-in'][(sit, sto, com)] -
m.e_sto_out[t, sit, sto, com] /
m.storage_dict['eff-out'][(sit, sto, com)])
And for setting the init value they have something like following:
# initialization of storage content in first timestep t[1]
# forced minimun storage content in final timestep t[len(m.t)]
# content[t=1] == storage capacity * fraction <= content[t=final]
def res_initial_and_final_storage_state_rule(m, t, sit, sto, com):
if t == m.t[1]: # first timestep (Pyomo uses 1-based indexing)
return (m.e_sto_con[t, sit, sto, com] ==
m.cap_sto_c[sit, sto, com] *
m.storage_dict['init'][(sit, sto, com)])
elif t == m.t[len(m.t)]: # last timestep
return (m.e_sto_con[t, sit, sto, com] >=
m.cap_sto_c[sit, sto, com] *
m.storage_dict['init'][(sit, sto, com)])
else:
return pyomo.Constraint.Skip
I hope this example helps you. You can use it change it or adapt it in your code-
Upvotes: 1