© Apress 2015

Michael Paluszek and Stephanie Thomas, MATLAB Recipes, 10.1007/978-1-4842-0559-4_10

10. Chemical Processes

Michael Paluszek and Stephanie Thomas2

(1)Princeton, New Jersey, USA

(2)Princeton Junction, New Jersey, USA

Electronic supplementary material: The online version of this chapter (doi: 10.​1007/​978-1-4842-0559-4_​10) contains supplementary material, which is available to authorized users.

In chemical engineering, the production of chemicals needs to be modeled and the production process controlled. Our example will be a simple process in which the pH of a mixed solution needs to be controlled. This problem is interesting because the process is highly nonlinear and the sensor model does not have an explicit solution for the pH measurement. Modeling the sensor will require use of the numerical solver fzero.

The specific chemical process that you will study consists of an acid (HNO3) stream, a buffer (NaHCO3) stream, and a base (NaOH) stream that are mixed in a stirred tank.1 This is based on a bench-scale experiment developed at the University of California, Santa Barbara (UCSB), to study chemical process control.2 Figure 10-1 shows a diagram of the system, with three incoming streams q1, q2, and q3, and a valve to the output stream q4, where you will measure pH. The goal is to achieve a neutral pH.

A335353_1_En_10_Fig1_HTML.gif
Figure 10-1. Chemical mixing problem

10.1 Modeling the Chemical Mixing Process

Problem

You want to model the chemical process consisting of an acid stream, a buffer stream, and a base stream that are mixed in a stirred tank.

Solution

Model the chemical equilibria by adding two reaction invariants for each inlet stream and write the dynamical equations using the invariants. These are coded in a right-hand-side function that also defines the model data structure.

How It Works

Reaction invariants are quantities whose values do not change during a reaction. Each is a combination of chemicals that do not vary. The inputs are nitric acid (HNO3), sodium bicarbonate or baking soda (NaHCO3), and sodium hydroxide or lye (NaOH). There is a pair of invariants for each input stream i. The two reaction invariants W a and W b are

$$ {W}_{ai}={left[{mathrm{H}}^{+}
ight]}_i-{left[{mathrm{OH}}^{-}
ight]}_i-{left[{mathrm{H}mathrm{CO}}_3^{-}
ight]}_i-2{left[{mathrm{CO}}_3^{=}
ight]}_i $$
(10.1)

$$ {W}_{bi}={left[{mathrm{H}}_2{mathrm{CO}}_3
ight]}_i+{left[{mathrm{H}mathrm{CO}}_3^{-}
ight]}_i+{left[{mathrm{CO}}_3^{=}
ight]}_i $$
(10.2)

I = 1 is for the acid stream, I = 2 for the buffer stream, i = 3 for the base stream, and i = 4 is for the mixed effluent. The dynamical equations for the effluent invariants are derived via mass balances to be

$$ {dot{W}}_{a4}=frac{1}{Ah}left({W}_{a1}-{W}_{a4}
ight){q}_1+frac{1}{Ah}left({W}_{a2}-{W}_{a4}
ight){q}_2+frac{1}{Ah}left({W}_{a3}-{W}_{a4}
ight){q}_3 $$
(10.3)

$$ {dot{W}}_{b4}=frac{1}{Ah}left({W}_{b1}-{W}_{b4}
ight){q}_1+frac{1}{Ah}left({W}_{b2}-{W}_{b4}
ight){q}_2+frac{1}{Ah}left({W}_{b3}-{W}_{b4}
ight){q}_3 $$
(10.4)
where q i is the volumetric flow rates for the i th stream, A is the cross-sectional area of the mixing tank, and h is the liquid level. The liquid level is governed by a differential equation

$$ dot{h}=frac{1}{A}left[{q}_1+{q}_2+{q}_3-{C}_v{left(h+z
ight)}^n
ight] $$
(10.5)
where C v is the valve coefficient, n is the valve exponent, and z is the vertical distance between the bottom of the mixing tank and the outlet of the effluent stream. You can measure h. Normally, you need to estimate the reaction invariants, but for this problem, you will assume they are measured. These equations are all first-order and are therefore the state equations for the system. The flow rates are all multiplied by the states, meaning that their influence on the derivatives is a product of the states and the streams. The differential equations for the effluent invariants are singular when h = 0. This is because if the tank is empty, the flows have to be zero.

The resulting right-hand-side function, RHSpH, is shown next. It follows the format needed by the RungeKutta integrator (see Recipe 6-2)—that is, RHS(t,x,d)—with a tilde replacing the first input, because the dynamics are independent of time. Note the data structure that is defined and returned if there are no inputs. This model has quite a few parameters, which are documented in the header.

%% RHSpH Dynamics of a chemical mixing process.

% The process consists of an acid (HNO3) stream, buffer (NaHCO3) stream,

% and base (NaOH) stream that are mixed in a stirred tank. The mixed effluent

% exits the tank through a valve. The chemical equilibria is modeled by

% introducing two reaction invariants for each inlet stream. i = 1 for the

% acid, i = 2 for the buffer, i = 3 for the base, and i = 4 for the effluent.

%

% + - - =

% wAi = [H ]i - [OH ]i - [HCO3 ]i - 2[CO3 ]i

% - =

% wBi = [H2CO3]i + [HCO3 ]i + 2[CO3 ]i

%

%% Forms

% d = RHSpH

% xDot = RHSpH( t, x, d )

%

%% Inputs

% t (1,1) Time, unused

% x (3,1) State [wA4;wB4;h]

% d (.) Structure

% .wA1 (1,1) Acid invariant A, (M)

% .wA2 (1,1) Buffer invariant A, (M)

% .wA3 (1,1) Base invariant A, (M)

% .wB1 (1,1) Acid invariant B, (M)

% .wB2 (1,1) Buffer invariant B, (M)

% .wB3 (1,1) Base invariant B, (M)

% .a (1,1) Cross-sectional area of mixing tank (cm2)

% .cV (1,1) Valve coefficient

% .n (1,1) Valve exponent

% .z (1,1) Vertical distance between bottom of

tank and outlet of effluent (cm)

% .q1 (1,1) Volumetric flow of HNO3 (ml/s)

% .q2 (1,1) Volumetric flow of NaHCO3 (ml/s)

% .q3 (1,1) Volumetric flow of NaOH (ml/s)

%

%% Outputs

% xDot (3,1) State derivative

%

%% Reference

% Henson, M. A. and D. E. Seborg. (1997.) Nonlinear Process

% Control, Prentice-Hall. pp. 207-210.

function xDot = RHSpH( ˜, x, d )

if ( nargin < 1 )

% Note: Cv was omitted in the reference; we calculated it assuming a constant

% liquid level in the tank of 14 cm.

d = struct('wA1',0.003,'wA2',0.03,'wA3',3.05e3,...

'wB1',0.0, 'wB2', 0.03,'wB3', 5.0e5,...

'a',207,'cV',4.5860777,'n',0.607,'z',11.5,...

'q1',16.6,'q2',0.55,'q3',15.6);

xDot = d;

return ;

end

wA4 = x(1);

wB4 = x(2);

h = x(3);

hA = 1/(h*d.a);

xDot = [hA*( (d.wA1wA4)*d.q1 + (d.wA2wA4)*d.q2 + (d.wA3wA4)*d.q3 );...

hA*( (d.wB1wB4)*d.q1 + (d.wB2wB4)*d.q2 + (d.wB3wB4)*d.q3 );...

d.q1 + d.q2 + d.q3d.cV*(h + d.z)ˆd.n];

The default values in the data structure are drawn from the data in the reference, with the exception of C v ; this was neglected by the reference, so we calculated a value for an equilibrium tank level.

ans =

wA1: 0.003

wA2:0.03

wA3:0.00305

wB1: 0

wB2: 0.03

wB3: 5e05

a: 207

cV: 4.5861

n: 0.607

z: 11.5

q1: 16.6

q2: 0.55

q3: 15.6

The goal of this chapter is to design an equilibrium point controller. We could rewrite the equations as linear equations in which each state and input is replaced with, for example, 
$$ {q}_3={q}_{30}+delta {q}_3 $$
(10.6)

$$ h={h}_0+delta h $$
(10.7)
where δq 3 is small. We could then formally derive the linear control system. However, we will leave that for the interested reader and just go ahead and implement a linear control system.

10.2 Sensing the pH of the Chemical Process

Problem

The pH sensor is modeled by a nonlinear equation that cannot be solved explicitly for pH.

Solution

Use the MATLAB fzero function to solve for pH.

How It Works

The equation for pH is 
$$ 0={W}_{a4}+{10}^{left(mathrm{p}mathrm{H}-14
ight)}-{10}^{-mathrm{p}mathrm{H}}+{W}_{b4}frac{1+2	imes {10}^{left(mathrm{p}mathrm{H}-p{K}_2
ight)}}{1+{10}^{left(p{K}_1-mathrm{p}mathrm{H}
ight)}+{10}^{left(mathrm{p}mathrm{H}-p{K}_2
ight)}} $$
(10.8)

Recall that W a4 and W b4 are the reaction invariants for the mixed effluent as defined in Recipe 10-1. pK 1 and pK 2 are the base-10 logarithms of the H2CO3 and 
$$ {mathrm{HCO}}_3^{-} $$
disassociation constants.

$$ p{K}_a=-{displaystyle { log}_{10}}{K}_a $$

The function that generates the measurement is PHSensor.

%% PHSensor Model pH measurement of a mixing process

% Compute pH as a function of wA4 and wB4 and also the slope of pH with

% respect to those states. Requires the use of fzero.

%

%% Forms

% pH = PHSensor( x, d )

% d = PHSensor( ' struct ' )

%

%% Inputs

% x (2,:) State [wA4;wB4]

% d (.) Data structure

% .pK1 (1,1) Base 10 log of a disassociation constant (H2CO3)

% .pK2 (1,1) Base 10 log of a disassociation constant (HCO3-)

%

%% Outputs

% pH (:,:) pH of the solution

%

%% Reference

% Henson, M. A. and D. E. Seborg. Nonlinear Process control, Prentice–Hall,

% 1997. pp. 207–210.

The body of PHSensor calls fzero to compute the pH. This requires an objective function that will be searched for a zero near the input point. Use a neutral pH of 7.0 as the initial condition for the optimization. The function is vectorized for multiple input states, computing a square matrix of pH with the combinations of W a4 and W b4.

% Compute the pH starting from neutral

n = size (x,2);

pH = zeros (n,n);

pH0 = 7.0;

for k = 1:n

for j = 1:n

d.wA4 = x(1,k);

d.wB4 = x(2,j);

pH(k,j) = fzero ( @Fun, pH0, [], d );

end

end

Tip

Use fzero to solve for the zero point for complex single equations. Use fminzero for sets of equations with multiple values to be found that minimize the function.

Notice that as per our usual pattern, we have defined a data structure d for passing data to the sensor model. Our two parameters are pK 1 and pK 2.

if ( ischar(x) )

pH = struct('pK1',- log10 (4.47e-7),'pK2',- log10 (5.62e-11));

return

end

Equation 10.8 is embodied in the subfunction Fun, which is passed to fzero.

function y = Fun( pH, d )

%%% PHSensor>Fun Function to be zeroed via fzero

% y = Fun( pH, d )

y = d.wA4 + 10ˆ(Ph14)10ˆ(pH) ...

+ d.wB4*(1 + 2*10ˆ(pHd.pK2))/(1 + 10ˆ(d.pK1pH) + 10ˆ(pHd.pK2));

A demo is included in the function, as suggested in the best practices described in the style recipes. The demo specifies a range of values for the states-the invariants—based on the numbers in the reference.

% Demo

if ( nargin < 1 )

x(1,:) = linspace (9e4,0);

x(2,:) = linspace (0,1e3);

d = PHSensor('struct');

PHSensor( x, d );

return

end

The results are plotted at the end of the main function.

if ( nargout == 0 )

h = figure ;

set (h,'Name','PHSensor');

mesh (pH)

xlabel ('WB4');

ylabel ('WA4');

zlabel ('pH')

grid on

rotate3d on

clear pH

end

The plotting uses the mesh function. It is important to remember that the rows of p correspond to Wa 4 and the columns to W b4. Columns are x and rows are y in the mesh plot. Figure 10-2 shows the mesh plot and also the alternative surf plot (with 'edgecolor' set to 'none'). Note the two MATLAB commands:

A335353_1_En_10_Fig2_HTML.gif
Figure 10-2. surf and mesh plots of the pH sensor output

grid on

rotate3d on

Always use the on to be certain that the commands are executed rather than toggled; otherwise, you can get unexpected results if you have just run another script or function with those commands.

Notice that the relationship between the pH and the reaction invariants is highly nonlinear. You would ideally like a relationship 
$$ pH=cleft[egin{array}{l}{W}_{a4}hfill \ {}{W}_{b4}hfill end{array}
ight] $$
(10.9)
where c is a 2 × 2 matrix with constant coefficients. This might be true in the flat regions, but it is not true in the “waterfall” region.

When using this function in a simulation, you need it to run as fast as possible, without any diagnostics installed for fzero. During debugging, however, you may need addition information. fzero can display information on each iteration by setting the Display option. For instance, with the 'iter' setting it will print information for each iteration. The updated fzero call is

pH(k,j) = fzero ( @Fun, pH0, optimset('Display','iter'), d );

and the results for a single state are

>> d = PHSensor('struct')

d =

pK1: 6.3497

pK2: 10.25

>> pH = PHSensor( [4.32e4;5.28e4], d )

Search for an interval around 7 containing a sign change:

Func-count a f(a) b f(b) Procedure

1 72.39821e07 72.39821e07 initial interval

3 6.802014.16536e05 7.19799 3.09792e05 search

Search for a zero in the interval [6.80201, 7.19799]:

Func-count x f(x) Procedure.

3 7.19799 3.09792e05 initial

4 7.0291 4.96758e06 interpolation

5 7.000281.88684e07 interpolation

6 7.00133 3.84365e09 interpolation

7 7.00131 2.86799e12 interpolation

8 7.00131 0 interpolation

Zero found in the interval [6.80201, 7.19799]

pH =

7.0013

This was a very rapid solution, as it is very near the starting point of 7.0. Note that fzero first found an interval containing a sign change, and then searched for the zero. fzero can also output diagnostic information when complete, instead of printing it during operation. For instance, if the call is

[pH(k,j),fval,exitflag,output] = fzero ( @Fun, pH0, [], d );

then the output structure is available, such as

output =

intervaliterations: 1

iterations: 5

funcCount: 8

algorithm: 'bisection,interpolation'

message: 'Zerofoundintheinterval[6.80201,7.19799]'

Note that the algorithm used, bisection, is listed along with the total number of iterations and function evaluations. Consider a slight variation of the input state, lowering Wb4 to 4e –4 M. The number of iterations jumps significantly.

>> pH = PHSensor( [4.32e4;4e4], d )

output =

intervaliterations: 8

iterations: 7

funcCount: 24

algorithm: 'bisection,interpolation'

message: 'Zerofoundintheinterval[4.76,9.24]'

pH =

9.022

In particular, note that viewing the diagnostic information for your problem can help confirm if your tolerances are suitable. Consider the final iterations of the previous case.

Search for a zero in the interval [4.76, 9.24]:

Func-count x f(x) Procedure

17 9.24 2.04571e05 initial

18 9.04068 1.42294e06 interpolation

19 9.02583 2.87604e07 interpolation

20 9.02207 5.59178e09 interpolation

21 9.02199 2.25694e11 interpolation

22 9.02199 1.7808e15 interpolation

23 9.02199 5.42101e20 interpolation

24 9.02199 5.42101e20 interpolation

The search pushed the function value all the way down to 5.4e − 20, which may be more restrictive than needed. The default tolerances can be viewed by getting the default options structure using optimset.

>> options = optimset('fzero')

options =

Display: 'notify'

MaxFunEvals: []

MaxIter: []

TolFun: []

TolX: 2.2204e16

FunValCheck: 'off'

OutputFcn: []

PlotFcns: []

The default tolerance on the function value, TolX, is 2.2204e-16. Note that you passed in the name of the selected optimization routine, fzero, to optimiset. The same can be done with fminbnd and fminsearch.

Tip

Use optimset with the name of the optimization function to get the default options structure.

Now consider that you want to evaluate how fzero performs over a range of inputs. Assume that you create a separate function for Fun and make a script to record extra data from output during a run. Figure 10-3 shows a plot using pcolor.of the resulting recorded function evaluations. You can see the rapid changes due to the nonlinearities of the model. The maximum number of function evaluations does not exceed 35.

A335353_1_En_10_Fig3_HTML.gif
Figure 10-3. Function evaluations for the PHSensor algorithm

The following is the augmented code creating the plot.

%% Script for debugging PHSensor algorithm

% Nominal operating conditions from the reference

x10 = −4.32e4;

x20 = 5.28e4;

x = [];

x(1,:) = linspace (2*x10,0);

x(2,:) = linspace (0,2*x20);

d = PHSensor('struct');

% Compute the pH starting from neutral

n = size (x,2);

pH = zeros (n,n);

fEvals = zeros (n,n);

pH0 = 7.0;

for k = 1:n

for j = 1:n

d.wA4 = x(1,k);

d.wB4 = x(2,j);

% Options: TolX, Display, FunValCheck

% ( ' TolX ' ,1e − 10);

% ( ' Display ' , ' iter ' )

% ( ' FunValCheck ' , ' on ' ) % no errors found for demo

options = optimset('FunValCheck','on');

[pH(k,j),fval,exitflag,output] = fzero ( @Fun, pH0, options, d );

fEvals(k,j) = output.funcCount;

end

end

figure ('Name','PH⊔Sensor');

surf (pH,'edgecolor','none')

xlabel ('WB4');

ylabel ('WA4');

zlabel ('pH')

grid on

rotate3d on

figure ('Name','Evaluations')

s = pcolor (x(2,:),x(1,:),fEvals);

set (s,'edgecolor','none')

xlabel ('WB4');

ylabel ('WA4');

colormap jet

title ('FunctionEvaluationsbyfzero')

10.3 Controlling the Effluent pH

Problem

You want to control the pH level in the mixing tank when the flow of acid or base varies.

Solution

You will vary the base stream, i = 3, to maintain the pH. This means changing the value of q 3 using a proportional integral controller. This allows you to handle step disturbances.

How It Works

A proportional integral controller is of the form 
$$ u=Kleft(1+frac{1}{	au }{displaystyle int}
ight)y $$
(10.10)
where u is the control, y is the measurement, τ is the integrator time constant, and K is the forward (proportional) gain. The control is u = q 3 and the measurement is y = pH. There is one control, q 3, and one output, pH. This makes this a single-input/single-output process. However, the connection between q 3 and pH involves three dynamical states: h, Wa 4, and Wb 4. The relationship between the states and pH is nonlinear. Another issue is that q 3 cannot be negative; that is, you cannot extract the base from the tank. This should not pose a problem if the equilibrium q 3 is high enough.

Despite these potential problems, this very simple controller works for this problem for a fairly wide range of disturbances. The equilibrium value is input with a perturbation that has an proportional and integral term. The integral term uses simpler Euler integration. The full script is described in the next recipe; here, attention is called to the lines implementing the control.

The control variables are defined next. The pH setpoint is neutral; that is, a pH of 7. kF is the forward gain and tau is the time constant from equation 10.10, set to 2 and 60 seconds, respectively. q3Set is the nominal setpoint for the base flow rate, taken from the reference.

%% Control design

pHSet = 7.0;

tau = 60.0; % (sec)

kF = 2.0; % forward gain

q3Set = 15.6; % (ml/s)

The following code snippet shows the implementation that takes place in a loop. The error is calculated as the difference between the modeled pH measurement and the pH setpoint. Note the Euler integration, where intErr is updated using simply the timestep times the error. Note also that there is a flag, controlIsOn, which allows you to run the script in open loop, without the control being applied.

% Proportional-integral Control

err = pHpHSet;

if controlIsOn

d.q3 = q3SetkF*(err + intErr/tau);

intErr = intErr + dT*err;

else

d.q3 = q3Set;

end

To rigorously determine the forward gain and time constant for this problem, you would need to linearize the right-hand side for the simulation at the operating point and do a rigorous single-input/single-output control design that involves Bode plots, Root-Locus, and other techniques. This is beyond the scope of this book. For now, simply select values that produce a reasonable response.

10.4 Simulating the Controlled pH Process

Problem

You want to simulate the stirred tank, mixing three streams—acid, buffer, and base—to demonstrate control of the pH level. The base stream is the control variable in response to perturbations in the buffer and acid streams.

Solution

Write a script PHProcessSimwith the controller, starting at an equilibrium state. Use the proportional-integral controller as derived in the previous recipe. The script will be structured to allow you to insert pulses in either or both the acid and buffer streams.

How It Works

The disturbances d are deviations in q 1 and q 2,

$$ d=left[egin{array}{r}hfill {q}_1\ {}hfill {q}_2end{array}
ight] $$
(10.11)
which are the acid and buffer streams. The base stream is q 3 and the reaction invariants for the mixed effluent are W a4 and W b4.

Specify the user inputs to the script first. You are putting it into an equilibrium state and will investigate small disturbances from steady-state. There is a flag, controlIsOn, for turning the control system on or off. The timestep and duration are determined by iterating over a few values.

%% User inputs

% Time (sec)

tEnd = 60*60;

dT = 1.0;

% States

wA4 = −4.32e4; % Reaction invariant A for effluent stream (M)

wB4 = 5.28e4; % Reaction invariant B for effluent stream (M)

h = 14.0; % liquid level (cm)

% Closed or open loop

controlIsOn = true;

The disturbances are modeled as pulses to d.q1 and d.q2. The user parameters are the size and the start/stop times of the pulses. This setup allows you to run cases similar to the reference.

% Disturbances

% The pulses will be applied according to the start and end times of tPulse:

% q1 = q10 + deltaQ1; and q2 = q20 + deltaQ2;

% Small pulse: 0.65 ml/s in q2

% Large pulses: 2.0 ml/s

% Very large pulses: 8.0 ml/s

deltaQ1 = 8.0; % +/− 1.5

deltaQ2 = 0.0; % 0.65 1.45 0.45 − 0.55 % values from reference

tPulse1 = [5 15]*60;

In the remainder of the script, you obtain the data structures defined in the previous recipes, specify the control parameters, and create the simulation loop. The measurements of the invariants are assumed to be exact; in practice, they need to be estimated. However, you should always test the controller under ideal conditions first to understand its behavior without complications. The pH measurement is modeled using PHSensor from Recipe 10-2. The right-hand side for the process is defined in Recipe 10-1. Integration is performed using the RungeKutta defined in Chapter 6.

%% Data format

dSensor = PHSensor('struct');

d = RHSpH;

%% Control design

pHSet = 7.0;

tau = 60.0; % (sec)

kF = 2.0; % forward gain

q3Set = 15.6; % (ml/s)

q10 = d.q1;

q20 = d.q2;

%% Run the simulation

% Number of sim steps

n = ceil (tEnd/dT);

% Plotting arrays

xP = zeros (7,n);

t = (0:n1)*dT;

% Initial states

x = [wA4;wB4;h];

intErr = 0;

for k = 1:n

% Measurement

dSensor.wA4 = x(1);

dSensor.wB4 = x(2);

pH = PHSensor( x, dSensor );

% Proportional-integral Control

err = pHpHSet;

if controlIsOn

d.q3 = q3Set - kF*(err + intErr/tau);

intErr = intErr + dT*err;

else

d.q3 = q3Set;

end

% Disturbance

if ( t(k) > tPulse1(1) && t(k) < tPulse1(2) )

d.q1 = q10 + deltaQ1;

else

d.q1 = q10;

end

if ( t(k) > tPulse2(1) && t(k) < tPulse2(2) )

d.q2 = q20 + deltaQ2;

else

d.q2 = q20;

end

% Store data for plotting

xP(:,k) = [x;pH;d.q1;d.q2;d.q3];

% Integrate one step

x = RungeKutta( @RHSpH, 0, x, dT, d );

end

%% Plot

[t,tL] = TimeLabel(t);

yL = {'W_{a4}' 'W_{b4}' 'h' 'pH' 'q_1' 'q_2' 'q_3'};

tTL = 'PHProcessControl';

if ˜controlIsOn

tTL = [tTL '⊔−⊔OpenLoop'];

end

PlotSet( t, xP,'xlabel',tL,'ylabel',yL,'plottitle',tTL,'figuretitle',tTL)

PlotSet( t, xP([4 7],:),'xlabel',tL,'ylabel',yL([4 7]),'plottitle',tTL,'figuretitle',tTL)

Now, you give results for running this script with some different pulses. The nominal plot gives all three states: the measured pH, the flow rates for the acid, base, and the buffer streams. A more compact plot shows just the pH and the commanded value of q 3. We added a line in the plotting code to amend the plot title for an open-loop response, so that if you run the script repeatedly, you can more easily identify the plots.

Tip

Use your control flags and string variables to customize the names of your plots.

Figure 10-4 shows the closed response with no disturbances at all, run for 30 simulated minutes. You can see that the values from the reference have not produced an exact equilibrium, but that the values achieved are quite close. Reaction invariant W b4 changes by less than 0.005 × 10−4; the liquid level h by less than 0.1 cm; and the base flow rate q 3 by about 0.05 ml/s. This is equivalent to a very small step response. Note the settling time is about 5 minutes. These results give you confidence that you have coded the problem correctly. You see this initial response in the following simulations, before the perturbations are applied.

A335353_1_En_10_Fig4_HTML.gif
Figure 10-4. Closed-loop response with no perturbations

Next, Figure 10-5 shows the open-loop response with a pulse of 0.65 ml/s in the buffer stream, starting at 20 minutes and ending at 40 minutes. Note that the pH rises to nearly 7.4 and q 3 does in fact stay constant at the setpoint. Figure 10-6 shows the closed-loop transients in the pH and base flow q 3. The pH rise is limited to less than 7.2 and the pH and base flow rate are reach equilibrium within about 10 minutes of the start and end of the pulse. This compares favorably with the plots in the reference, which compare adaptive and nonadaptive nonlinear control schemes.

A335353_1_En_10_Fig5_HTML.gif
Figure 10-5. Open-loop response with a 0.65 ml/s pulse in q2
A335353_1_En_10_Fig6_HTML.gif
Figure 10-6. Performance of the controller with a 0.65 ml/s pulse in q2

Figure 10-7 shows the transients with larger, offset perturbations of 2 ml/s in both q 1 and q 2. The pulse in q 1 is applied from 5 to 15 minutes and the pulse in q 2 from 25 to 40 minutes. Figure 10-8 has plots of just the pH and control flow q 3 .

A335353_1_En_10_Fig7_HTML.gif
Figure 10-7. Performance of the controller with large perturbations of 2 ml/s in q1 and q2
A335353_1_En_10_Fig8_HTML.gif
Figure 10-8. Larger plots of the q1 /q2 perturbation results

Figure 10-9 shows the transients with a very large perturbation in q 2 of 8 ml/s from 5 to 35 minutes. The controller no longer works very well, with a much longer settling time than the previous examples and the base flow rate q 3 still dropping at the end of the pulse. A pulse value of 10 ml/s causes the simulation to “blow up,” or produce imaginary values. It is always necessary to see the limits of the control performance in a nonlinear system.

A335353_1_En_10_Fig9_HTML.gif
Figure 10-9. Performance of the controller with a very large perturbation (8 ml/s) in q2

Finally, since you are using a numerical optimization routine , it is instructive to profile the simulation to determine the proportion of execution time spent on fzero. The Profiler can be accessed from the Command Window button called Run and Time. The summary from running the pH simulation is shown in Figure 10-10. Out of nearly 19 seconds spent in the simulation, fully 12.6 seconds are spent inside fzero itself. Only 4.4 seconds were spent integrating, of which 3.4 seconds were spent in the right-hand side. The summary has hyperlinks to the individual functions, which are timed line by line. Figure 10-11 shows the time spent inside fzero, with percentages calculated in addition to absolute times. The objective function, PHSensor > Fun, was called 56,131 times, taking only 1.27 seconds (10% of the execution time). Significant chunks of time were spent in sprintf and optimget.

A335353_1_En_10_Fig10_HTML.gif
Figure 10-10. Profiler summary from the simulation
A335353_1_En_10_Fig11_HTML.gif
Figure 10-11. Profiler results for fzero
Tip

Always do a run with the Profiler when you are implementing a numerical search or optimization routine. This gives you insight into the number of iterations used and any unsuspected bugs in your code.

In this case, there is not much optimization that can be done, as most of the time is spent in fzero itself and not in the objective function, but you wouldn’t have known that without running the analysis. Whenever you are using numerical tools and have a script or function taking more than a second or two to run, analysis with Profiler is merited.

Summary

This chapter demonstrated how to write the dynamics and implement a simple control law for a chemical process. The process is highly nonlinear, but you can control the process with a simple proportional integral controller. The pH sensor does not have a closed form solution and you need the MATLAB fzero function to find pH from the invariants. The use of MATLAB plotting functions mesh and surf for showing three-dimensional data were demonstrated. You used a simulation script to evaluate the performance of the controller for a variety of conditions and to run the script in the Profiler to analyze the time spent on the numerical routines. Table 10-1 lists the code developed in this chapter.

Table 10-1. Chapter Code Listing

File

Description

PHSensor

Model pH measurement of a mixing process.

PHProcessSim

Simulation of a pH neutralization process.

RHSpH

Dynamics of a chemical mixing process.

SensorTest

Script to test the sensor algorithm.

Footnotes

1 Henson, M. A. and D. E. Seborg, Nonlinear Process Control, Prentice-Hall, 1997.

2 Henson, M. and D. Seborg, “Adaptive Nonlinear Control of a pH Neutralization Process”, IEEE Transactions on Control Systems Technology, vol. 2, no. 3, August 1994.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset