不可行与不可行的区别IMODE=6
以及可行的IMODE=3
那是IMODE=3
case 允许优化器调整温度初始条件。优化器认识到初始条件可以更改,因此将其修改为 75,以保持可行并最大限度地减少未来的能耗。
from gekko import GEKKO
import numpy as np
m = GEKKO(remote=False)
m.time = np.linspace(0,23,24)
#initialize variables
T_external = [50.,50.,50.,50.,45.,45.,45.,60.,60.,63.,\
64.,45.,45.,50.,52.,53.,53.,54.,54.,\
53.,52.,51.,50.,45.]
temp_low = [55.,55.,55.,55.,55.,55.,55.,68.,68.,68.,68.,\
55.,55.,68.,68.,68.,68.,55.,55.,55.,55.,55.,55.,55.]
temp_upper = [75.,75.,75.,75.,75.,75.,75.,70.,70.,70.,70.,75.,\
75.,70.,70.,70.,70.,75.,75.,75.,75.,75.,75.,75.]
TOU_v = [0.05,0.05,0.05,0.05,0.05,0.05,0.05,200.,200.,200.,200.,\
200.,200.,200.,200.,200.,200.,200.,200.,200.,200.,0.05,\
0.05,0.05]
b = m.Param(value=1.)
k = m.Param(value=0.05)
T_e = m.Param(value=T_external)
TL = m.Param(value=temp_low)
TH = m.Param(value=temp_upper)
TOU = m.Param(value=TOU_v)
u = m.MV(lb=0, ub=1)
u.STATUS = 1 # allow optimizer to change
# Controlled Variable
T = m.SV(value=75)
m.Equations([T>=TL,T<=TH])
m.Equation(T.dt() == k*(T_e-T) + b*u)
m.Minimize(TOU*u)
m.options.IMODE = 6
m.solve(disp=True,debug=True)
import matplotlib.pyplot as plt
plt.subplot(2,1,1)
plt.plot(m.time,temp_low,'k--')
plt.plot(m.time,temp_upper,'k--')
plt.plot(m.time,T.value,'r-')
plt.ylabel('Temperature')
plt.subplot(2,1,2)
plt.step(m.time,u.value,'b:')
plt.ylabel('Heater')
plt.xlabel('Time (hr)')
plt.show()
如果你再去一天(48 小时),你可能会发现这个问题最终将不可行,因为较小的加热器b=1
无法满足温度较低的限制。
使用的优点之一IMODE=6
是你可以写出微分方程,而不是自己进行离散化。和IMODE=3
,您可以使用欧拉方法来求解微分方程。默认离散化为IMODE>=4
is NODES=2
,相当于欧拉有限差分法。环境NODES=3-6
提高准确度有限元正交配置 https://apmonitor.com/do/index.php/Main/OrthogonalCollocation.