我正在使用 PyOMO 来模拟半批量反应。
考虑一个描述半间歇式反应器的 ODE 系统,其中一种反应物在t1单位时间内以给定的体积流量进料,反应一直持续到t end,并且显然t1 < t end。
要指定流程中的停止点,我可以使用条件规则(假设t1 = 3.5*60):
def _vol_flow_in_schedule(mod,t):
if t<=3.5*60:
return mod.vol_flow_in[t] == (12.3/1000)/(3.5*60)
else:
return mod.vol_flow_in[t] == 0
m1.vol_flow_in_schedule = Constraint(m1.time,rule=_vol_flow_in_schedule)
这将产生不连续性(然后我的模型不会收敛)。我想要做的是使用一个 sigmoidal 函数,它将流转换为零而没有不连续性。
尽管我需要参考时间变量本身,但要实现 sigmoidal。
下面的 MATLAB 代码给了我想要的结果:
t=[0:1:500];
acc=2; %Acceleration parameter, higher values yields sharper change.
time_of_step=3.5*60;
init_value = (12.3/1000)/(3.5*60);
end_value = 0;
sigmoidal=(init_value+(end_value-init_value)/2)...
+((end_value-init_value)/2)*atan((t-time_of_step)*acc)/atan(max(t));
但是,此实现需要在函数中显式地使用时间变量。如何访问 PyOMO 规则中的时间变量?我尝试了以下方法,但出现“无法将标量组件 't_of_step' 视为数组”错误:
m1.init_value = Param(initialize = (12.3/1000)/(3.5*60))
m1.end_value = Param(initialize = 0)
m1.t_of_step = Param(initialize = 210)
m1.acc = Param(initialize = 5)
.
.
def _vol_flow_sigmoidal (mod,t):
return mod.vol_flow_in[t] == (mod.init_value+(mod.end_value-mod.init_value)/2)+((mod.end_value-mod.init_value)/2)*atan((t-mod.t_of_step)*mod.acc)/atan(1500)
m1.vol_flow_sigmoidal = Constraint(m1.time,rule=_vol_flow_sigmoidal)
希望我已经清楚地描述了我所追求的。欢迎任何提示,
谢谢! 萨尔