I’m trying to model an unsteady-state CSTR with discrete-event PI controller updates using MTK’s acausal component-based modeling framework, but I’m having trouble with @discrete_events (or @continuous_events) not being able to “see” connector variable information from outside components. Am I doing something wrong or are these begin blocks simply not supported with the acausal modeling framework yet?
@mtkmodel PIcontroller begin
@components begin
readingsIn = Stream()
signalOut = ValveSignal()
end
@variables begin
I_err(t) = 0 # Integral error
end
@parameters begin
c_BSP = 0.32 # Desired concentration (mol/L)
K_b = 0.0 # Bias (-)
K_c = 9.0 # Proportional gain (-)
K_I = 0.18 # Integral gain (-)
eventStart = 200 # Enable PI Controller at t=200 min
eventInterval = 30 # Update signal every 30 mins
s = 0 # No initial signal to open valve
end
@equations begin
D(I_err) ~ c_BSP - readingsIn.c_B
signalOut.s ~ s
end
@discrete_events begin
((mod(t-eventStart,eventInterval) == 0) & (t >= eventStart)) => [s ~ K_b + K_c*(c_BSP - readingsIn.c_B) + K_I*I_err]
end
end
I’m able to connect all my components, use @mtkbuild
, create an ODEProblem()
, but when I get to solve()
, I get ERROR: UndefVarError: picontroller₊readingsIn₊c_B not defined
. I’ve isolated this as the issue because whenever I replace readingsIn.c_B
in the discrete_events block with some number, everything runs properly (although I get the wrong solution of course).
I’ve also tried something like this
@mtkmodel PIcontroller begin
@components begin
readingsIn = Stream()
signalOut = ValveSignal()
end
@variables begin
I_err(t) = 0 # Integral error
B(t)
end
@parameters begin
c_BSP = 0.32 # Desired concentration (mol/L)
K_b = 0.0 # Bias (-)
K_c = 9.0 # Proportional gain (-)
K_I = 0.18 # Integral gain (-)
eventStart = 200 # Enable PI Controller at t=200 min
eventInterval = 30 # Update signal every 30 mins
s = 0 # No initial signal to open valve
end
@equations begin
D(I_err) ~ c_BSP - B
B ~ readingsIn.c_B
signalOut.s ~ s
end
@discrete_events begin
((mod(t-eventStart,eventInterval) == 0) & (t >= eventStart)) => [s ~ K_b + K_c*(c_BSP - B) + K_I*I_err]
end
end
but @discrete_events
can’t see B
either. I’ve found that @discrete_events
can only see B
if I do something like D(B) ~ 0
, but then I can’t do B ~ readingsIn.c_B
because @mtkbuild
will tell me I have too many equations. Any insight would be appreciated.