Reputation: 734
I'm trying to reach a final condition subject to many Differential and Algebraic Equations. There is the option to change parameters in the model or adjust the initial condition to meet the final target. It is easy to do this with an adjustable parameter, but how can the final condition be met with an adjustable initial condition in Python Gekko?
import numpy as np
from gekko import GEKKO
import matplotlib.pyplot as plt
# simulate
m = GEKKO() # create GEKKO model
k = m.Param(0.1) # constant
y = m.Var(5.0) # create GEKKO variable
m.Equation(y.dt()==-k*y) # create GEKKO equation
m.time = np.linspace(0,20) # time points
m.options.IMODE = 4
m.solve(disp=False)
plt.plot(m.time,y,'r-',linewidth=2,label='k=0.1')
# adjust k to meet target
m = GEKKO() # create GEKKO model
k = m.FV(0.1); k.STATUS=1 # adjustable parameter
y = m.Var(5.0)
m.Equation(y.dt()==-k*y)
m.time = np.linspace(0,20,50)
m.options.IMODE = 6
p = np.zeros(50); p[-1]=1
final = m.Param(p)
m.Minimize(final*(y-1)**2)
m.solve(disp=False)
kv = k.value[0]
plt.plot(m.time,y,'k:',linewidth=2,label='k='+str(kv))
plt.plot([20],[1],'bo',markersize=5,label='target')
plt.xlabel('time')
plt.ylabel('y(t)')
plt.legend()
plt.show()
Upvotes: 0
Views: 179
Reputation: 14346
Set fixed_initial=False
to calculate the initial condition as shown in the Model Building Gekko documentation.
y = m.Var(5.0,fixed_initial=False)
Additional details are in the Gekko Documentation about m.free_initial(y)
as a function if the variable needs to be fixed or calculated after it is defined.
import numpy as np
from gekko import GEKKO
import matplotlib.pyplot as plt
# simulate
m = GEKKO() # create GEKKO model
k = m.Param(0.1) # constant
y = m.Var(5.0) # create GEKKO variable
m.Equation(y.dt()==-k*y) # create GEKKO equation
m.time = np.linspace(0,20) # time points
m.options.IMODE = 4
m.solve(disp=False)
plt.plot(m.time,y,'r-',linewidth=2,label='IC=5')
# adjust initial condition to meet target
m = GEKKO() # create GEKKO model
y = m.Var(5.0,fixed_initial=False)
k = 0.1
m.Equation(y.dt()==-k*y)
m.time = np.linspace(0,20,50)
m.options.IMODE = 6
p = np.zeros(50); p[-1]=1
final = m.Param(p)
m.Minimize(final*(y-1)**2)
m.solve(disp=False)
plt.plot(m.time,y,'k:',linewidth=2,label='IC='+str(y.value[0]))
plt.plot([20],[1],'bo',markersize=5,label='target')
plt.xlabel('time')
plt.ylabel('y(t)')
plt.legend()
plt.show()
Upvotes: 1