I recently started using CPLEX integrated in python for my master project and I have a hard time with one of my variables. I am modelling the charge and discharge of a battery in function of the wind and solar power as well as electricity market prices. All my variables for charge, discharge and production are well defined but my battery state of charge ends up being null at all times after solving. When calling get values of this variable i get a list of zeros (with sol the solution of the optimization and Ebes the name of the State of charge):
sol.get_values(Ebes[t]for t in time)
It is even unfeasible that this variable would be null as i also have the constraints in the model :
for t in time:
mdl.add_constraint(Ebes[t]>=Ebmin)
mdl.add_constraint(Ebes[t]<=Ebmax)
When I display the model before solving with print(mdl.export_to_string())
it shows that Ebes is constrained to be higher than Ebmin(=20) for all the time steps. The only hint I get is that the name of the variables in there is slightly different from the others. In here the variables of Ebes are named _Ebes_date whereas the other variables are named for example Pdischarge_date and not _Pdischarge_date. I guess this "_" before the name shows that there is a problem but i can't manage to find what to change.
My variables are defined as:
Ebes=mdl.continuous_var_dict(time,name='Ebes')
for i in range(len(time)):
if i==0:
mdl.add_constraint(Ebes[time[0]]==Ebes[time[len(time)-1]]*(1-etaleak)+Pcha[time[0]]*etacha*dt-(Pdis[time[0]]/etadis*dt))
else:
t=time[i]
tm=time[i-1]
mdl.add_constraint(Ebes[t]==Ebes[tm]*(1-etaleak)+Pcha[t]*etacha*dt-(Pdis[t]/etadis*dt))
Thank you if you take time to answer me :)
The whole example:
import pandas as pd
from docplex.mp.model import Model
ind=['01_09_2016 00','01_09_2016 01','01_09_2016 02','01_09_2016 03','01_09_2016 04']#[1,2,3,4,5]
M=pd.Series(data=[10,30,30,15,30],index=ind)
P=pd.DataFrame(data={'Time':ind,'DK2_wind':[0.3,0.24,0.14,0.18,0.22],'DK2_solar':[0,0,0,0,0.01]}).set_index('Time',drop=True)
mdl=Model('dispatch')
time=P.index
Psolar=300 #MW
Pwind= 400 #MW
P.DK2_solar=P.DK2_solar*Psolar
P.DK2_wind=P.DK2_wind*Pwind
Pres=P.sum(axis=1) #MW
Pmax=800 #MW
#Battery parameters:
Pbmax= 50 #MW
Ebmax= 100 #MWh
Ebmin= 20 #MWh
Pbal =mdl.continuous_var_dict(time,name='Pbal')
Pcha =mdl.continuous_var_dict(time,name='Pcharge')
Pdis =mdl.continuous_var_dict(time,name='Pdischarge')
Ebes=mdl.continuous_var_dict(time,name='Ebes')
switch=mdl.binary_var_dict(time,name='switch')
for t in time:
mdl.add_constraint(Pbal[t]==Pres[t]+Pdis[t]-Pcha[t])
for t in time:
mdl.add_constraint(Pdis[t]<=Pbmax*(1-switch[t]))
for t in time:
mdl.add_constraint(Pdis[t]>=0)
for t in time:
mdl.add_constraint(Pcha[t]<=Pbmax*switch[t])
for t in time:
mdl.add_constraint(Pcha[t]>=0)
for t in time:
mdl.add_constraint(Ebes[t]>=Ebmin)
for t in time:
mdl.add_constraint(Ebes[t]<=Ebmax)
for i in range(len(time)):
if i==0:
mdl.add_constraint(Ebes[time[0]]==Ebes[time[len(time)-1]]+Pcha[time[0]]-Pdis[time[0]])
else:
t=time[i]
tm=time[i-1]
mdl.add_constraint(Ebes[t]==Ebes[tm]+Pcha[t]-Pdis[t])
mdl.maximize(mdl.sum((Pbal[t]*M[t]) for t in time))
sol=mdl.solve(url=URLmt,key=Mykey,log_output=True)
sol_Ebess=sol.get_values(Ebes[t]for t in time)
sol_Ebess
sol.solve_details.status
So here the sol_Ebess is null for all indices. if I change ind to be numbers instead it works and Ebess is equal to the real value.