EV Battery Optimization  hitting processing error?
AnsweredHi all,
I'm working on an academic project trying to find least cost charging for vehicle to building battery banks (there are 70 small batteries in one bank that will be used as building energy resource). This is my first time with Gurobi and I can't figure out where I'm going wrong. I get this error message and I know that 217 solutions cannot be right.
Solution count 2: 217.615 217.615 Solve interrupted Best objective 2.176154998085e+02, best bound 2.175542385020e+02, gap 0.0282%
N = 70 #number of batteries in the bank
T = 24 #number of hours optimizing over
dis_max = 2 #discharging max [kWh]
ch_max = 2 #charging max [kWh]
mu_ch = 0.95 #charging efficiency
mu_dis = 0.95 #discharging efficiency
#list data
C_grid = [1.39,1.39,1.39,1.39,1.39,1.39,1.39,3.33,3.33,3.33,3.33,3.33,3.33,3.33,3.33,3.33,3.33,3.33,3.33,3.33,3.33,3.33,1.39,1.39] #price array (should have 1 value for each hour of the year)
SOC_list = [50*1.7]*24
SOC_max = [70*1.7]*24
build_demand = [9.5,9.38,10.19,10.08,11.63,11.44,10.77,15.12,31.05,38.27,44.49,47.74,44.94,55.42,60.44,61.18,46.64,74.58,99.54,96.27,88.33,72.63,12.49,10.76]
#indexed data
costs = {hour: cost for hour, cost in enumerate(C_grid)}#cost of grid power
SOC_min = {hour: SOC for hour, SOC in enumerate(SOC_list)} #minimum state of charge for total battery bank (right now just using one numvber for all 24 hours)
P_build = {hour: demand for hour, demand in enumerate(build_demand)} #power demand from building
#model initalization
m = gp.Model("EV")
#variables
#grid power variables
P_grid = m.addVars(T,ub=GRB.INFINITY, lb=0, name = "P_grid", vtype = GRB.CONTINUOUS)
#charging power variables
P_dis = m.addVars(N, T, lb=0, name = "P_dis", vtype = GRB.CONTINUOUS)
P_ch = m.addVars(N, T, lb=0, name = "P_ch", vtype = GRB.CONTINUOUS)
#binary charging variables
charging = m.addVars(N, T, name = 'charging', vtype=GRB.BINARY)
discharging = m.addVars(N, T, name = 'discharging', vtype=GRB.BINARY)
#individual SOC variables
SOC_batt = m.addVars(N, T, name = 'SOC_batt', vtype = GRB.CONTINUOUS)
m.update()
#objective
obj = gp.quicksum(costs[t]*P_grid[t] for t in range(T))
#equality constraints
#power balance
m.addConstrs((P_grid[t] + P_dis.sum('*', t) == P_build[t] + P_ch.sum('*', t)) for t in range(T))
#SOC
m.addConstrs((SOC_batt[i, t] == SOC_batt[i, t1] + (charging[i, t] * mu_ch)  (discharging[i, t] / mu_dis)) for i in range(N) for t in range(1,T))
#inequality constraints
#SOC
m.addConstrs((SOC_min[t] <= SOC_batt.sum('*', t)) for t in range(T))
m.addConstrs((SOC_batt.sum('*', t) <= SOC_max[t]) for t in range(T))
#charging limits
m.addConstrs((P_dis[i,t] <= discharging[i,t] * dis_max)for i in range(N) for t in range(T))
m.addConstrs((P_ch[i,t] <= charging[i,t] * ch_max)for i in range(N) for t in range(T))
#charging and discharging can't happen simultaneously
m.addConstrs((charging[i,t] + discharging[i,t] <= 1) for i in range(N) for t in range(1,T))
m.addConstrs((charging[i,t] + discharging[i,t] >= 0) for i in range(N) for t in range(1,T))
m.setObjective(obj, sense=GRB.MINIMIZE)
m.optimize()

Hi Alison,
Your screenshot shows a solution count of 2, which means Gurobi found 2 solutions during the solve. Both solutions have the objective value of 217.615 and are at an optimality gap of 0.0282%.
You may want to solve it to optimality and check if the optimal objective value is as expected. If not, you can take the following steps to find the source of the error:

Check that the model is built as per your expectations. One way to do this is to write your model in the LP file format, using \(\texttt{model.write("mymodel.lp")}\), and review the objective, variables and constraints in this file. The LP file can be opened with any text editor.
 If you know a solution that gives a better objective value than the optimal solution found by the solver, pass it to Gurobi and see what happens. To do this, you can fix the bounds of binary variables in the model to their values in your solution, using \(\texttt{var.UB=your_var_value}\) and \(\texttt{var.LB=your_var_value}\), and solve the fixed model. If the fixed model becomes infeasible, run the computeIIS() method to get the set of constraints and variables that makes it infeasible. To this end, please see our articles How do I determine why my model is infeasible? and How do I use 'compute IIS' to find a subset of constraints that are causing model infeasibility?.
Best regards,
Simran0 
Please sign in to leave a comment.
Comments
1 comment