2

I'm trying to complete a year-long battery optimization problem (8760 hours). "ind_1" and "ind_2" are lists of length 8760 containing 0s/1s. Certain hours of the year may earn additional revenue, so these indicator lists are used to distinguish those hours (further used in the maximization function).

m = Gekko(remote=False)
#variables
e_battery = m.Var(lb=0, ub=4000, value=2000) #energy in battery at time t, battery size 4 MWh, initial value is 2MWh
command = m.Var(lb=-1000, ub=1000) #command power -1 to 1 (in MW)
e_price = m.Param(value = price) #price is a list of 8760 values
ind_1 = m.Param(value = ind_1) 
ind_2 = m.Param(value = ind_2)
m.time = np.linspace(0,8759, 8760)
m.Equation(e_battery.dt() == e_battery + command)
m.Maximize((-command)*(e_price + ind_1*ind1_price + ind_2*ind2_price))
m.options.IMODE = 6
m.solve()

When I run the above model, it runs for about 20 iteration then returns the error: "@error: Solution Not Found". The objective of this task is to return an array of 8760 values (the command variable) which maximizes the return. Any ideas where this error comes from?

luk
  • 41
  • 2

1 Answers1

0

It looks like one of the equations isn't correct:

m.Equation(e_battery.dt() == e_battery + command)

This causes an exponential rise in e_battery that exceeds the upper bound. It should probably be:

m.Equation(e_battery.dt() == command)

There is a specific error code that gives insight on why the solver failed to find a solution. The two most common are Maximum Iterations and Infeasible Solution. If it is Maximum Iterations then try setting m.options.MAX_ITER to a higher number (up to 1000?). If it is Infeasible solution then look at infeasibilities.txt file in the run directory m.path to find the constraint(s) that are causing the problem. The other thing to try is to use a smaller time horizon initially to verify that it works on something with about 100 time steps.

from gekko import Gekko
import numpy as np
m = Gekko(remote=False)
#variables
n = 100
price=np.ones(n)
e_battery = m.Var(lb=0, ub=4000, value=2000) #energy in battery at time t
# battery size 4 MWh, initial value is 2MWh
command = m.Var(lb=-1000, ub=1000) #command power -1 to 1 (in MW)
e_price = m.Param(value = price) #price is a list of 8760 values
ind_1=1; ind_2=1
ind1_price=1; ind2_price=1
ind_1 = m.Param(value = ind_1) 
ind_2 = m.Param(value = ind_2)
m.time = np.linspace(0,n-1,n)
m.Equation(e_battery.dt() == command)
m.Maximize((-command)*(e_price + ind_1*ind1_price + ind_2*ind2_price))
m.options.IMODE = 6
m.solve()

This gives a successful solution:

EXIT: Optimal Solution Found.

 The solution was found.

 The final value of the objective function is  -6000.00005999999
 
 ---------------------------------------------------
 Solver         :  IPOPT (v3.12)
 Solution time  :  0.05 sec
 Objective      :  -6000.00005999999
 Successful solution
 ---------------------------------------------------
John Hedengren
  • 12,068
  • 1
  • 21
  • 25
  • Hi John, Thank you so much for your detailed response. Does the following code suggestion update the "e_battery" variable? ''' m.Equation(e_battery.dt() == command) ''' After every iteration, the value of "e_battery+command" should fall within the upper and lower bounds of the battery SoC limits (0-4 MWh) – luk Dec 13 '21 at 14:42
  • Yes, that is `d(e_battery)/dt = command`. The value of `e_battery` changes if `command` is non-zero. – John Hedengren Dec 13 '21 at 20:06
  • 1
    thank you so much. Your suggestions worked for me! – luk Dec 14 '21 at 19:37
  • 1
    This may be another question entirely but figured I'd ask here. I'm trying to add another constraint st the battery does at most 2 cycles every 24 hours (one full charge and discharge). The constraint is a little complex since the FULL problem horizon is 8760 hours, but every 24 hours the cycle condition has to be met. Would you know of any similar examples in gekko (consisting of 2 time horizons). My initial idea was to sum the battery operation for each day - but still don't know how to address the multiple time horizons. Any thoughts would help! – luk Dec 14 '21 at 20:33
  • Yes, that is probably a separate question. Go ahead and try something and post the example code if it doesn't work. – John Hedengren Dec 15 '21 at 20:43