我是 Gekko 的新手,我正在尝试模拟生产过程。该模型按预期工作,但我无法理解如何实现一个约束输出变量最小输出的方程。我的代码:
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
maxspeed = 30 # rev/hr
minspeed = 2 #rev/hr
lowrev = 1/(maxspeed/3600) # how fast can we go as sec/rev
highrev = 1/(minspeed/3600) # ow slow can we go as sec/rev
batchsize = 0.5
m = GEKKO(remote=False)
m.time = np.linspace(0,200,201)
tfr = m.Param(value=54.2)
subf = m.Param(value=13.47)
drumd = m.Param(value=2.9)
a1m = m.Param(value=1814.28)
dl = m.Param(value=0.42)
drumspeed = m.MV(value=400, lb=lowrev, ub=highrev)
drumspeed.STATUS = 1
drumspeed.DMAX = 2
filtrationvol = m.Var(value=0, lb=0)
m.Equation(filtrationvol == tfr*(m.sqrt(4*a1m*m.acos(1-
2*dl/drumd)*drumspeed/drumd))/(2*a1m*subf*drumspeed)) # output model
m.Maximize(filtrationvol)
m.options.IMODE = 6 # control mode
m.solve(disp=True)
我想将可变过滤卷的总输出限制为最大 0.5,这意味着我想最大化输出但只能达到某个点。我一直在玩 m.sum 和 m.vsum 但没有成功。
答案 0 :(得分:1)
使用积分函数得到总过滤量。
m.Equation(total_Vfilt == m.integral(filtrationvol))
您可以使用 total_Vfilt<0.5
包含硬约束,也可以使用 CV
类型设置软约束(目标函数)。方程的重新排列使求解器更容易,因为它避免了 m.sqrt()
和潜在的除以零,如果鼓速度需要变为零。
m.Equation((2*a1m*subf*drumspeed*filtrationvol/tfr)**2 \
==(4*a1m*m.acos(1-2*dl/drumd)*drumspeed/drumd))
带有 COLDSTART=1
的初始化策略也有助于求解器,因为它设置了 STATUS=0
以在优化之前进行模拟并获得更好的初始猜测。
m.options.COLDSTART = 1
m.solve(disp=False)
m.options.TIME_SHIFT= 0
m.options.COLDSTART = 0
m.solve(disp=True)
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
maxspeed = 30 # rev/hr
minspeed = 2 #rev/hr
lowrev = 1/(maxspeed/3600) # how fast can we go as sec/rev
highrev = 1/(minspeed/3600) # ow slow can we go as sec/rev
batchsize = 0.5
m = GEKKO(remote=False)
m.time = np.linspace(0,200,201)
tfr = m.Param(value=54.2)
subf = m.Param(value=13.47)
drumd = m.Param(value=2.9)
a1m = m.Param(value=1814.28)
dl = m.Param(value=0.42)
drumspeed = m.MV(value=400, lb=lowrev, ub=highrev)
drumspeed.STATUS = 1
drumspeed.DMAX = 2
filtrationvol = m.Var(value=0.0, lb=0)
m.Equation((2*a1m*subf*drumspeed*filtrationvol/tfr)**2 \
==(4*a1m*m.acos(1-2*dl/drumd)*drumspeed/drumd))
m.Maximize(filtrationvol)
# summation with an integral
total_Vfilt = m.CV(0,lb=0) # hard constraint with ub=0.5
# total_Vfilt.UPPER = 0.5 # or adjust .UPPER
m.Equation(total_Vfilt == m.integral(filtrationvol))
# soft constraint with abs() value penalty for exceeding limit
total_Vfilt.SPHI = 0.5; total_Vfilt.SPLO = 0.0
total_Vfilt.WSPHI = 1000
total_Vfilt.STATUS = 1
m.options.IMODE = 6 # control mode
m.options.SOLVER = 3 # IPOPT solver
m.options.COLDSTART = 1
m.solve(disp=False)
m.options.TIME_SHIFT= 0
m.options.COLDSTART = 0
m.solve(disp=True)
plt.figure(figsize=(12,6))
plt.subplot(4,1,1)
plt.plot(m.time,drumspeed.value,'r-',label='Sdrum')
plt.legend()
plt.subplot(4,1,2)
plt.plot(m.time,drumspeed.value,'r-',label='Sdrum')
plt.plot([0,200],[lowrev,lowrev],'k:',label='Limits')
plt.plot([0,200],[highrev,highrev],'k:')
plt.legend()
plt.subplot(4,1,3)
plt.plot(m.time,filtrationvol.value,'b--',label='Vfilt')
plt.legend()
plt.subplot(4,1,4)
plt.plot(m.time,total_Vfilt.value,'b:',\
label=r'$\int(Vfilt)$')
plt.plot([0,200],[0.5,0.5],'k-',label='Limit')
plt.legend()
plt.xlabel('Batch / Time')
plt.show()