CHE3005W: Computing
Chemical Engineering
University of Cape Town
Feb 2016
Klaus Mller
Scilab:
systems of non-linear equations
and systems of ordinary differential equations
CONTENTS
Contents
I
Introduction
1.1 Single equations . . . . . . . . . . . . . . . . . . . . . . . .
1.1.1 Recognising non-linear equations . . . . . . . . . . .
1.1.2 Arrangement of the equations for computer solution
1.1.3 One equation, multiple solutions . . . . . . . . . . .
1.1.4 Using the knowledge/features of the equation . . . .
1.2 Systems of equations . . . . . . . . . . . . . . . . . . . . .
II
5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . .
. . . . . .
. . . . . .
reactions
. . . . . .
. . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
11
12
13
15
15
17
18
.
.
.
.
.
.
20
20
22
23
23
23
26
28
Introduction
5.1 Single equations . . . . . . . . . . . . . . . . . . . . . . . . .
5.1.1 Recognising ODES that can be solved on a computer
5.1.2 Arrangement of the equations for computer solution .
5.1.3 Using the knowledge/features of the equation . . . . .
5.2 Systems of equations . . . . . . . . . . . . . . . . . . . . . .
5.2.1 Stiff systems . . . . . . . . . . . . . . . . . . . . . .
5.2.2 Solving higher order eqations . . . . . . . . . . . . . .
How to use Scilabs ode
6.1 The form of the equations . . .
6.2 The scilab command . . . . . .
6.2.1 Single equation example
6.2.2 Multi-equation example .
4
4
4
5
5
5
6
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
29
29
29
30
30
30
32
32
.
.
.
.
34
34
34
36
37
CONTENTS
39
39
39
40
40
40
40
Part I
Introduction
The first step is that you need to recognise the type of equations that you have. These are often
disguised within chemical engineering notation. The second step is that you need to arrange
them in a way that the computer can solve.
The techniques and tools shown here can also be used to solve linear equations, although this
is not a common or recommended practice.
1.1
1.1.1
Single equations
Recognising non-linear equations
(1)
(2)
Z 3 (1 B)Z 2 + (A 2B 3B 2 )Z (AB B 2 B 3 ) = 0
(3)
X
A0
Kp =
FB0
(1 X) FA0 X Pt
2
(4)
(5)
(6)
Equation 1 is easy to recognise as a cubic equation in x while equation 2 is more general nonlinear equation. Equation 3 and its sub-equations represents the well known Peng-Robinson
equation of state written in a form that is solved for Z, the compressibilty factor with B and
B being constants. This equation, although its not immediately obvious is identical in form
and behaviour to equation 1. Equation 4 is the well know flash tank equation with Zi and Ki
supplied as species constants, and for more than two species, this is a non-linear equation in .
Equation 5 is the CSTR mole balance for a reaction A + B C + D with rA = kCA CB2 and
arranged in terms of conversion, X.
For the last equation 6 it is more difficult recognise that this represents the chemical equilibrium
Kp
of the gas phase reaction A + B C and it is solved for the equilibrium conversion, X, given
Pt , FA0 , FB0 and Kp which depends on T .
INTRODUCTION
1.1.2
In order to use a computer to solve these equations, they all need to be arranged in a form
equation as a function of variable = 0
so, equations 1 to 4 are already in the right form, but equation 6 needs to be re-arranged, thus
FB0
X FA0 + 1 X
=0
Kp
FB0
(1 X) FA0 X Pt
However, this is not all, since in a computer solution, it is possible to choose X values such that
, both of which yield a division by zero and will cause the solver to fail. To
X = 1 and X = FFB0
A0
avoid this, the equation can be further re-arranged
FB0
Kp Pt (1 X) FFB0
X
+
1
X
=0
(7)
FA0
A0
and it is clear that this is a quadratic in X (of course easily solved by hand, right). Equation 7
is the stable form of equation 6 that is used for computer solution.
1.1.3
One annoying feature of non-linear equations, is that although there is only one equation and
ONE variable to find, there can be more than one answer that satisfies the equation. Equation
1 is a cubic and thus for one set of constanst a, b, c, d can have 1 value of x, while for another
set of constants 3 values of x are possible. What this means is that with a Newton type solver,
you have to solve the equation 3 times using different starting guesses to yield the 3 diffferent
values of x.
Equation 2 contains a log(x) which means that x cannot be negative and a sin(x) which means
that some form of periodic (infinitely repeated) solution of x will be obtained. Finding all the
values of x that satisfy this humble equation would be a mammoth task!
Although not commonly stated in classical chemical engineering text books, equation 4 can have
multiple values of . The mole balance equation 5 will have 3 possible values of the conversion
X. Lastly, equation 7 will have two values of X.
Note that complex roots have not been mentioned here. It is important to note that a newton
type solver CANNOT determine the solution if it is complex (yes there is a way, but we will
not learn about it here). For polynomials ONLY, Scilab has an elegant procedure roots, which
finds all real and complex roots of any polynomial - we will use it later.
1.1.4
It is quite clear from section 1.1.3 that to ensure that the right value is used, it is necessary to
have some knowledge of the physical system you are analysing and the equations that you are
working with. Lets now look at these equations from a physical perspective.
The cubic equation of state, equation 3 only the real roots are valid and more so the largest
and smallest roots of needed. Thus it will be necessary to solve for all three roots when they
exist and sort them, largest to smallest.
In the flash equation, = VF , represents the vapour-liquid split of a feed stream (F ) into vapour
(V ) and liquid (L), and this can only take on values between 0 and 1, where 0 is all liquid and
1 is all vapour. The solver must then be run to ensure that these values are obtained.
The CSTR mole balance, equation 5, the conversion, X, can have only values between 0 and
1. Values of X that are outside this range must be discarded - in fact they should yield some
INTRODUCTION
anomalous results. What happens if there are two values of X between 0 and 1? Multiple steady
states are real physical phenomena, but will not be addressed here.
Similarly, the equilbrium conversion obtained from equation 7 must lie between 0 and 1 and can
have only one value.
What this tells you is that, although I will show you how to used the Scilab solvers as a canned
tool, knowledge of the system and equations will separate the canned students from the
chemical engineers.
1.2
Systems of equations
The same rules as above apply, however, there are a few anomalies. It is more difficult t recognise
these equations. The concept is as follows, all the equations are arranged such that
F (X) = 0
where F is a vector of equations and X = [x1 , x2 , x3 , ...] is a
f1 ([x1 , x2 , x3 , ...]) 0
f2 ([x1 , x2 , x3 , ...]) 0
f ([x , x , x , ...]) = 0
3 1 2 3
..
..
.
.
(8)
(9)
(10)
a2 x + b2 y + c2 z + d2 = 0
a3 x + b3 y + c3 z + d3 = 0
These equations are non-linear combinations of linear, quadratic and cubic terms. Since the
quadratic and cubic terms each can have 2 and 3 solutions respectively, it becomes quite obvious
that there could well be may many possible combinations of values of (x, y , z) that will satisfy
the equations or alternatively the quadratic equation may have only a complex solution in which
case any attempts to solve the system with a standaed solver will fail.
INTRODUCTION
(11)
(12)
(13)
(14)
F z1 V y1 Lx1 = 0
(15)
F z2 V y2 Lx2 = 0
F z3 V y3 Lx3 = 0
(16)
(17)
y1 K1 x1 = 0
(18)
y2 K2 x2 = 0
(19)
y3 K3 x3 = 0
(20)
3 component balances;
(21)
An equation count gives yields 8, the variables to find are the liquid phase molar flow rate
(L) mole fractions (x1 , x2 , x3 ) and the vapour phase molar flow rate (V ) and mole fractions
(y1 , y2 , y3 ), which also yields 8, thus this system can be solved, since number of equations =
number of unkowns. In fact with a little algebra, equation 4 can be obtained.
Next, consider a liquid phase CSTR with 2 reactions, A B and B C, with rA = k1 CA2
and rB = k1 CA2 k2 CB and rC = k2 CB and assuming a pure feed of A, the mole balance for each
species is;
k1 V 2
C =0
0 A
k1 V 2 k2 V
CB +
C
CB = 0
0 A
0
k2 V
CC +
CB = 0
0
CA0 CA
(22)
(23)
(24)
An equation count yields 3 equations. The unknowns are the exit concentrations, (CA , CB , CC ),
since the feed is fully specified. Thus the system can be solved (Note: you can easily solve this
by hand).
Next, consider chemical equilibrium for the same liquid phase system of 2 chemical reactions,
A B and B C with equilibrium constants KAB and KBC , the system of equations to be
solved are starting with pure A;
KAB =
CC
CB
; KBC =
CA
CB
(25)
INTRODUCTION
An equation count yields 2 equations, while the number of unknowns are the concentrations,
(CA , CB , CC ), which makes 3. Another equation is needed. One option is to use a stoichiometric
table to convert to conversions, as was done in equation 7, one for each reaction, X1 and X2 ,
thus satisfying the number of equations. An alternative, sometimes more elegant method is the
use the knowledge of the system, that is elemental balances or mole balances to look for more
equations. In this case since real chemicals are not used, mole balances are the only option.
Since the number of moles in the system never changes, it means that the starting moles must
equal the moles at equilibrium, thus CA0 V = (CA + CB + CC ) V . The re-arranging and adding
the mole balance yields the required 3 equations;
KAB CA CB = 0
(26)
KBC CB CC = 0
(27)
CA0 CA CB CC = 0
(28)
(29)
a2 log(x) + b2 exp(y ) + c2 z 2 + d2 = 0
(30)
a3 log(x) + b3 exp(y ) + c3 z + d3 = 0
(31)
at first glance they may appear non-linear, but infact they are linear equations in log(x), exp(y ), z 2 ,
since the equation can be separated as
a1 b1 c1 log(x) d1
a2 b2 c2 exp(y ) = d2
(32)
a3 b3 c3 z 2 d2
which is a linear equation that can be solved for log(x), exp(y ), z 2 and thus yields x, y , z.
Hopefully, this has given a feel for the kind of systems that can be solved with a non-linear
equation solver. The following will look at how to use Scilabs fsolve how to obtain solutions
to such equations.
Scilabs fsolve is a Newton solver that has been supercharged and turbochaged with a DSG
gearbox and launch control (funny enough it still gets beaten sometimes). It has a close cousin,
lsqrsolve, which is strictly a non-linear least squares solver, but that can be implemented
without any extra effort to solve non-linear equations. There are also some other options, all of
which are based on scilabs optim solver, although it has many additional features, it is inferior
both in performance and stability to fsolve. We will only consider fsolve here. It is the world
standard and is found in almost every numerical package world-wide.
The scilab command to start the solver is
[ x [ , v [ , i n f o ] ] ] = f s o l v e ( x0 , f c t [ , f j a c ] [ , t o l ] )
or in its simplest form
x= f s o l v e ( x0 , f c t )
here
x is the solution to the equations, it is a vector, and represents the solution to the unknowns
in the order that they have been assigned in the function;
v (optional) is a vector of the error or residual of each of the equations, that is, it is the 0
part of the general expression, F (x) 0 and its closeness to zero is a measure of how
accurately the solution has been found. Generally the elements of v should all be less than
108 .
info (optional) is an integer that indicates if the solution process has been successful. When
info=1 then all has gone well and the solver reached a solution. All other values of info
indicate that there is a problem with either the input or the solution and you have to look
again at the equations and yur code.
x0 is the initial guess to the equations, it is a vector and has exactly the same number of elements
as x and they must also be in the same order as the unknowns have been assigned.
fct is the name of the function, that is
function f=fct ( x )
The name, fct can be any valid scilab function name, like model, cstr, equilib, etc
fjac (Optional) is the name of a function that calculate the jacobian of the vector of equations.
The jacobian is a square matrix representing the partial derivatives of each function with
respect to each variable, thus, every element, i, j is given by
Ji,j =
fi (x)
xj
(33)
10
f u n c t i o n f =m o d e l ( x )
f =x ^2+x 2 // t h e e q u a t i o n comes h e r e a s a f u n c t i o n o f x
endfunction
and the calling squence shall look like this
x0 =1 // t h e i n i t i a l g u e s s f o r x
x= f s o l v e ( x0 , m o d e l ) // e x e c u t e t h e s o l v e r
p r i n t f ( % f , x ) // p r i n t t h e a n s w e r
When there are more than more that one equation, then the function follows this structure
f u n c t i o n f =m o d e l ( x )
// x i s a v e c t o r o f 3 o r more v a l u e s , s o m e t i m e s when t h e t h e
x v e c t o r r e f e r s to d i f f e r e n t v a r i a b l e s , l i k e flow r a t e
and t e m p e r a t u r e , i t becomes c o n v e n i e n t t o rename them ,
f o r example as below
y1=x ( 1 )
y2=x ( 2 )
y3=x ( 3 )
// t h i s r e n a m i n g i s n o t n e e d e d , x ( i ) c a n be u s e d d i r e c t l y i n
the equation below
f ( 1 ) =y1+y2+y3 3
f ( 2 ) =y1 ^2+ y2 ^2+ y3 ^210
f ( 3 ) =y1+y2 ^2+ y3 ^32
// t h e r e must be 3 e q u a t i o n s , t h u s 3 f ( ) v a l u e s , t h e f ( )
v e c t o r h a s t h e same number o f e l e m e n t s a s t h e x ( ) v e c t o r
endfunction
and the calling sequence is
x0 = [ 1 1 1 ] // t h e r e a r e t h r e e i n i t i a l v a l u e s
x= f s o l v e ( x0 , m o d e l )
p r i n t f ( % f \ , x ) // t h e r e w i l l be 3 a n s w e r s
3
3.1
11
Solve the cubic equation for its root f (x) = ax 3 + bx 2 + cx + d with a = 1, b = 2, c = 3 and
d = 2, starting at x = 1. Use Scilabs roots solver to cross check your answer. Also plot a
graph of the function to get a visual impression of the the equation you are trying to solve and
plot on it the roots you have found.
Solution
//single non-linear equation, a polynomial
// f(x)=a*x^3+b*x^2+c*x+d
// $$f(x)=ax^3 + bx^2 + cx + d $$
//finding a single root using fsolve
//check the answer using the polynomial roots solver, "roots"
clear;clc
//define the function
a=1
b=2
c=-3
d=-2
function f=model(x)
f=a*x^3+b*x^2+c*x+d
endfunction
x0=1 //initial guess
x=fsolve(x0,model)
printf('\n')
printf('x from fsolve = %f\n',x)
//using the the polynomial solver roots
//this finds all the solutions, in the console --> type help roots
//the vector pcoeffs lists the polynomial constants in decreasing order
//of the powers of x, thus in order a,b,c,d
pcoeffs=[a b c d]
xsolution=roots(pcoeffs)
printf('\n')
printf('x from roots = %f\n',xsolution)
//making a plot
z=linspace(-3,2,50)'
for i=1:length(z)
f(i)=model(z(i))
end
scf(1);clf
plot(z,f,'-red')
plot([-3 2],[0 0],'-blk');
plot(xsolution,zeros(3,1),'ored')
3.2
12
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
=
=
=
=
=
1.342923
1.342923
1.342923
1.342923
1.342923
starting
starting
starting
starting
starting
from
from
from
from
from
initial
initial
initial
initial
initial
guess
guess
guess
guess
guess
3.000000
4.000000
5.000000
6.000000
7.000000
x
x
x
x
x
from
from
from
from
from
13
3.3
Solution
//single non-linear equation, a polynomial
// f(x)=a*x^3+b*x^2+c*x+d
// $$f(x)=ax^3 + bx^2 + cx + d $$
//finding a single root using fsolve
//check the answer using the polynomial roots solver, "roots"
clear;clc
//define the function
a=1
b=-1
c=-3
d=-2
function f=model(x)
f=a*x^3+b*x^2+c*x+d
endfunction
x0=1 //initial guess
[x1,v1,info]=fsolve(x0,model)
printf('\n')
printf('x from fsolve = %f\n',x1)
printf('error in f(x) = %f\n',v1)
printf('status of fsolve = %i\n',info)
//the value of info=4
//that means that the solve has not converged to a solution
//looking at the error, v=-0.731646
//it is not close to zero, thus the error criterion v < 1e-10 has not been met
//thus this is an invalid solution
x0=2 //initial guess
[x2,v2,info]=fsolve(x0,model)
printf('\n')
printf('x from fsolve = %f\n',x2)
printf('error in f(x) = %f\n',v2)
printf('status of fsolve = %i\n',info)
x0=3 //initial guess
[x3,v3,info]=fsolve(x0,model)
printf('\n')
printf('x from fsolve = %f\n',x3)
printf('error in f(x) = %f\n',v3)
printf('status of fsolve = %i\n',info)
//using the the polynomial solver roots
//this finds all the solutions, in the console --> type help roots
//the vector pcoeffs lists the polynomial constants in decreasing order
//of the powers of x
pcoeffs=[a b c d]
xsolution=roots(pcoeffs)
printf('\n')
printf('x from roots = %f + %f i\n',real(xsolution),imag(xsolution))
//the variable xsolutions is actual a complex variable a + bi
//thus you have to print the two parts
//making a plot
z=linspace(-2,3,50)'
for i=1:length(z)
f(i)=model(z(i))
end
scf(1);clf
plot(z,f,'-red')
plot([-2 3],[0 0],'-blk');
plot(x1,v1,'ored')
plot(x2,v2,'squarered')
plot(x3,v3,'oblue')
14
15
3.4
3.4.1
Applications
Chemical equilibrium with single reaction
The equation
Kp Pt (1 X)
FB0
FA0
X X FFB0
+
1
X
=0
A0
Kp
represents the chemical equilibrium of the gas phase reaction A + B C and it is solved for
the equilibrium conversion, X, given Pt , FA0 , FB0 and Kp which depends on T . The parameters
needed are FA0 = 1, FB0 = 1, Kp = 0.5, Pt = 10. The effect of pressure can also be explored
by repeatedly solving the system. Repeatedly solve this equation for the pressure between 1 and
10 incrementing in steps of 1.
Solution
X from fsolve = 0.833333
error in f(x) = 0.000000
status of fsolve = 1
X = 0.333333 at a pressure
X = 0.500000 at a pressure
X = 0.600000 at a pressure
X = 0.666667 at a pressure
X = 0.714286 at a pressure
X = 0.750000 at a pressure
X = 0.777778 at a pressure
X = 0.800000 at a pressure
X = 0.818182 at a pressure
of
of
of
of
of
of
of
of
of
1.000000
2.000000
3.000000
4.000000
5.000000
6.000000
7.000000
8.000000
9.000000
16
3.4.2
17
The equation
n
X
Zi (Ki 1)
=0
1
+
(K
i 1)
i=1
is the well know flash tank equation with Zi and Ki supplied as species constants, and for more
than two species, this is a non-linear equation in . The equation is to be solved for 3 species.
The parameters are Z = [0.3, 0.4, 0.3]0 and K = [0.5, 1.1, 2]0 . Report the vapour-liquid split,
= V /F .
Solution
psi=V/F from fsolve = 0.639757 error in f(x) = 0.000000 status of fsolve = 1
psi=V/F from fsolve = 0.639757 error in f(x) = 0.000000 status of fsolve = 1
psi=V/F from fsolve = 0.639757 error in f(x) = 0.000000 status of fsolve = 1
//Solving the Rachford-Rice flash equation for phase split
//3 components
// f(psi)=sum(Z*(K-1)/(1+psi*(K-1))=0
// $$f(\psi)=\sum_i^3 \left(\dfrac{Z(K-1)}{1+\psi(K-1)} \right)=0 $$
//finding a single root using fsolve
clear;clc
//define the function
Z=[0.3 0.4 0.3]'
K=[0.5 1.1 2]'
//you can formula the function using vector calculations
function f=model(psi)
f=sum(Z.*(K-1)./(1+psi*(K-1)))
endfunction
//or you can write outeach term and sum them
function f=model1(psi)
f=Z(1)*(K(1)-1)/(1+psi*(K(1)-1)) + ..
Z(2)*(K(2)-1)/(1+psi*(K(2)-1)) + ..
Z(3)*(K(3)-1)/(1+psi*(K(3)-1))
endfunction
//you can formulate the equations using a loop with term by term addition
function f=model2(psi)
f=0
for i=1:3
f=f+Z(i)*(K(i)-1)/(1+psi*(K(i)-1))
end
endfunction
//now you can see the real reason for getting to understand how scilab uses
//vector calculations
psi0=0.5 //initial guess, must be between 0 and 1
[psi,v,info]=fsolve(psi0,model)
printf('\n')
printf('psi=V/F from fsolve = %f\n',psi)
printf('error in f(x) = %f\n',v)
printf('status of fsolve = %i\n',info)
[psi,v,info]=fsolve(psi0,model1)
printf('\n')
printf('psi=V/F from fsolve = %f\n',psi)
printf('error in f(x) = %f\n',v)
printf('status of fsolve = %i\n',info)
[psi,v,info]=fsolve(psi0,model2)
printf('\n')
printf('psi=V/F from fsolve = %f\n',psi)
printf('error in f(x) = %f\n',v)
printf('status of fsolve = %i\n',info)
3.4.3
18
Homework!!!!!!!!!!!!
3
V (1 X)
FA0 X kCA0
FB0
FA0
2
=0
(34)
Equation 34 is the CSTR mole balance for a reaction A + B C + D with rA = kCA CB2 and
arranged in terms of conversion, X.
The parameters you need to solve the problem are FA0 = 1, FB0 = 1, k = 1, V = 1, CA0 = 1.
Write a scilab programme using fsolve that will determine the conversion. In the scilab console
display, (i)the conversion, (ii)the error in the function at the solution point and (iii)the status
of the solver.
Solution
//Solving the CSTR design equation for conversion
//for the reation A+B = C+D, ra=-kCaCb^2
// f(X)=Fa0*X-k*Ca0^3*V*(1-X)*(Fb0/Fa0-X)^2=0
// $$f(X)=F_{A0}X-kC_{A0}^3V(1-X)(F_{B0}/F_{A0}-X)^2=0 $$
//finding a single root using fsolve
clear;clc
//define the function
Fa0=1
Fb0=1
k=1
V=1
Ca0=1
function f=model(X)
f=Fa0*X-k*Ca0^3*V*(1-X)*(Fb0/Fa0-X)^2
endfunction
X0=0.5 //initial guess, must be between 0 and 1
[X,v,info]=fsolve(X0,model)
printf('\n')
printf('X from fsolve = %f\n',X)
printf('error in f(x) = %f\n',v)
printf('status of fsolve = %i\n',info)
// it is possible to vary the volume and calculate conversion as a function
//of volume by solving this equation repeatedly
dV=0.2
V=0.1-dV
printf('\n')
for i=1:10
V=V+dV
//the volume is changed here at each interation. It is very important that
//the variable used here, the V, is exactly the same as the variable used
//in the function, case sensitive.
//The variable V is global and when its changed here it is also updated
//in the function
[X,v,info]=fsolve(X0,model)
printf('X = %f at a volume of %f\n',X,V)
//to plot the data, need to store the values of V and X in vectors
//thus
Vr(i)=V
Xr(i)=X
end
scf(1);clf
plot(Vr,Xr,'-ored')
X
X
X
X
X
X
X
X
=
=
=
=
=
=
=
=
0.229083
0.271092
0.303757
0.330338
0.352655
0.371823
0.388576
0.403421
at
at
at
at
at
at
at
at
a
a
a
a
a
a
a
a
volume
volume
volume
volume
volume
volume
volume
volume
of
of
of
of
of
of
of
of
0.500000
0.700000
0.900000
1.100000
1.300000
1.500000
1.700000
1.900000
19
4
4.1
20
f1 = 0.000000
f2 = 0.000000
f3 = 0.000000
f1 = 0.000000
f2 = 0.000000
f3 = 0.000000
f1 = 0.000000
f2 = 0.000000
f3 = 0.000000
f1 = 0.000000
f2 = 0.000000
f3 = 0.000000
f1 = 0.000000
f2 = 0.000000
f3 = 0.000000
21
4.2
22
4.3
4.3.1
23
Applications
Chemical equilibrium for multiple reactions
Consider chemical equilibrium for the same liquid phase system of 2 chemical reactions, A B
and B C with equilibrium constants KAB and KBC , the system of equations to be solved are
starting with pure A are;
KAB CA CB = 0
KBC CB CC = 0
CA0 CA CB CC = 0
These are to be solved for (CA , CB , CC ). The parameters needed are CA0 = 1, KAB = 0.5,
KBC = 2.
Solution
C from fsolve = 0.400000
C from fsolve = 0.200000
C from fsolve = 0.400000
error in f(x) = 0.000000
error in f(x) = 0.000000
error in f(x) = -0.000000
status of fsolve = 1
4.3.2
Flash calculation
Consider the flash of a 3 component system in which the feed (F ), its composition, (z1 , z2 , z3 )
and the phase equilibrium constants (K1 , K2 , K3 ) are given; The equations that describe this
system are;
F V L=0
24
F z1 V y1 Lx1 = 0
F z2 V y2 Lx2 = 0
F z3 V y3 Lx3 = 0
y1 K1 x1 = 0
y2 K2 x2 = 0
y3 K3 x3 = 0
(y1 x1 ) + (y2 x2 ) + (y3 x3 ) = 0
An equation count gives yields 8, the variables to find are the liquid phase molar flow rate
(L) mole fractions (x1 , x2 , x3 ) and the vapour phase molar flow rate (V ) and mole fractions
(y1 , y2 , y3 ), which also yields 8, thus this system can be solved, since number of equations =
number of unkowns. The parameters for this system are F = 1, Z = [0.3, 0.4, 0.3]0 and
K = [0.5, 1.1, 2]0 . Report the vapour-liquid split, = V /F and the compositions of the leaving
streams.
Solution
=0.639757
y(1)=0.220549
y(2)=0.413543
y(3)=0.365908
x(1)=0.441098
x(2)=0.375948
x(3)=0.182954
L=0.360243
psi=0.639757
error in f(x) = 0.000000
error in f(x) = -0.000000
error in f(x) = 0.000000
error in f(x) = -0.000000
error in f(x) = 0.000000
error in f(x) = -0.000000
error in f(x) = 0.000000
error in f(x) = 0.000000
status of fsolve = 1
V=0.639757
y(1)=0.220549
y(2)=0.413543
y(3)=0.365908
x(1)=0.441098
x(2)=0.375948
x(3)=0.182954
L=0.360243
psi=0.639757
error in f(x) = 0.000000
error in f(x) = -0.000000
error in f(x) = 0.000000
error in f(x) = -0.000000
//Solving the flash equation for phase split using the mass balance
equations
//3 components
// f1=F-V-L
1 equation
// f2=F*z(i)-V*y(i)-L*x(i) 3 equations
// f3=y(i)-K(i)*x(i) 3 equations
// f4=sum(x(i)-y(i)) 1 equation
// $$f_1=F-V-L=0 $$
// $$f_2=FZ_i-Vy_i-Lx_i=0 $$
// $$f_3=y_i-K_ix_i=0 $$
// $$f_4=\sum_i^3 \left( x_i-y_i \right) =0 $$
//
clear;clc
X0=[V;y;x;L]
[X,v,info]=fsolve(X0,model1)
printf('\n')
printf('V=%f\n',X(1))
printf('y(1)=%f\n',X(2))
printf('y(2)=%f\n',X(3))
printf('y(3)=%f\n',X(4))
printf('x(1)=%f\n',X(5))
printf('x(2)=%f\n',X(6))
printf('x(3)=%f\n',X(7))
printf('L=%f\n',X(8))
printf('psi=%f\n',X(1)/F)
printf('error in f(x) = %f\n',v)
printf('status of fsolve = %i\n',info)
X0=[V;y;x;L]
[X,v,info]=fsolve(X0,model)
printf('\n')
printf('V=%f\n',X(1))
printf('y(1)=%f\n',X(2))
printf('y(2)=%f\n',X(3))
printf('y(3)=%f\n',X(4))
printf('x(1)=%f\n',X(5))
printf('x(2)=%f\n',X(6))
printf('x(3)=%f\n',X(7))
printf('L=%f\n',X(8))
printf('psi=%f\n',X(1)/F)
printf('error in f(x) = %f\n',v)
printf('status of fsolve = %i\n',info)
endfunction
//now you can see the real reason for getting to understand how
scilab uses
//vector calculations
4
SOLVING MULTIPLE EQUATIONS
25
4.3.3
26
Homework!!!!!!!!!!!!!!
Consider a liquid phase CSTR with 2 reactions, A B and B C, with rA = k1 CA2 and
rB = k1 CA2 k2 CB and rC = k2 CB and assuming a pure feed of A, the mole balance for each
species is;
k1 V 2
C =0
0 A
k1 V 2 k2 V
C
CB = 0
CB +
0 A
0
k2 V
CC +
CB = 0
0
CA0 CA
(35)
(36)
(37)
An equation count yields 3 equations. The unknowns are the exit concentrations, (CA , CB , CC ),
since the feed is fully specified. Thus the system can be solved.
The parameters you need to solve the problem are FA0 = 1, k1 = 1, k2 = 1, V = 1, CA0 = 1,
0 = 1.
Write a scilab programme using fsolve that will determine the exit concentrations of the 3
species. In the scilab console display, (i)the exit concentration of the 3 species, (ii)the error in
the functions (3 values) at the solution point and (iii)the status of the solver.
Solution
C(1) from fsolve = 0.618034
C(2) from fsolve = 0.190983
C(3) from fsolve = 0.190983
error in f(1) = -0.000000
error in f(2) = 0.000000
error in f(3) = 0.000000
status of fsolve = 1
C(1) = 0.916080 at volume 0.100000
C(2) = 0.076291 at volume 0.100000
C(3) = 0.007629 at volume 0.100000
C(1) = 0.805399 at volume 0.300000
C(2) = 0.149693 at volume 0.300000
C(3) = 0.044908 at volume 0.300000
C(1) = 0.732051 at volume 0.500000
C(2) = 0.178633 at volume 0.500000
C(3) = 0.089316 at volume 0.500000
C(1) = 0.678113 at volume 0.700000
C(2) = 0.189345 at volume 0.700000
C(3) = 0.132542 at volume 0.700000
C(1) = 0.635978 at volume 0.900000
C(2) = 0.191590 at volume 0.900000
C(3) = 0.172431 at volume 0.900000
C(1) = 0.601723 at volume 1.100000
C(2) = 0.189656 at volume 1.100000
C(3) = 0.208621 at volume 1.100000
C(1) = 0.573069 at volume 1.300000
C(2) = 0.185622 at volume 1.300000
C(3) = 0.241309 at volume 1.300000
C(1)
C(2)
C(3)
C(1)
C(2)
C(3)
C(1)
C(2)
C(3)
=
=
=
=
=
=
=
=
=
0.548584
0.180566
0.270850
0.527308
0.175071
0.297621
0.508573
0.169458
0.321970
at
at
at
at
at
at
at
at
at
volume
volume
volume
volume
volume
volume
volume
volume
volume
1.500000
1.500000
1.500000
1.700000
1.700000
1.700000
1.900000
1.900000
1.900000
27
28
29
Part II
Introduction
The first step is that you need to recognise the type of equations that you have. These are often
disguised within chemical engineering notation. The second step is that you need to arrange
them in a way that the computer can solve.
The purpose of this section is to show you how easy it is to solve differential equations, to
take away the myth its a differential equation - I cannot solve it and replace it with wow you
can solve differential equations - you must be a rocket scientist and hopefully you will see that
solving ODEs is just as pleasant as having a cup of tea or drinking a beer.
This section is by no means complete, but a very subtle introduction to solving odes. Itis not
possible to cover all possible bases and situations. I have tried to include the obvious pnes that
come to mind, possibly a little biased to reactor design!
5.1
5.1.1
Single equations
Recognising ODES that can be solved on a computer
= CA0 CA kCAn
dt
FB0
dX
X
(1 X) FA0 X
FA0
=k
2
F
dV
B0
FB0
KE FA0 + 1 X
+
1
X
FA0
dP
P 0 T FT
G(1 ) 150(1 )
= 0
; 0 =
+ 1.75G
dz
P T0 FT 0
0 DP 3
DP
INTRODUCTION
5.1.2
30
all equations must always be arranged such that they have the form
f =
dy
= f (t, y )
dt
where the derivative along is present in the left hand side and all other variables are on the right
hand side and may not contain any derivatives. Thus,
R2
p
dh
= Qin A 2gh
dt
need to be written as
dh
Qin
A p
=
2gh
dt
R2 R2
in order for it to be solved on the computer. There is not much else to know here.
5.1.3
5.2
Systems of equations
A simple example
dy1
= y1 t y2
dt
dy2
= y2 t y1
dt
INTRODUCTION
31
GMx
(x 2 + y 2 )3/2
= vx
=
GMy
(x 2 + y 2 )3/2
= vy
= (1 + X)
dW
P
with i =
dV
KE (FA + FB + FC ) RT
(FA + FB + FC )2 RT
"
#
2
dFB
FA F B
P
FC
P
= k
dV
KE (FA + FB + FC ) RT
(FA + FB + FC )2 RT
"
#
2
dFC
FA FB
P
FC
P
=k
dV
KE (FA + FB + FC ) RT
(FA + FB + FC )2 RT
Consider a multiple reaction system in a liquid phase PFR;
A+B Q
A+QR
B+R S
INTRODUCTION
32
which yields
dCA
d
dCB
d
dCQ
d
dCR
d
dCS
d
= k1 CA CB k2 CA CQ
= k1 CA CB k3 CB CR
= k1 CA CB k2 CA CQ
= k2 CA CQ k3 CB CR
= k3 CB CR
5.2.1
Stiff systems
These are unique features of equation systems in which the one variable changes very rapidly
and the other very slowly. Consider
dy1
= 0.01y1
dt
dy2
= 104 y2
dt
which have the solution, y1 = y0 exp(0.01t) and y2 = y0 exp(104 t). Thus what happens
is that y2 goes to zero after about 0.001 time units, while y1 has not yet responded. y1 only
startys decreasing after about 10 times units. The stability of most solvers is dependent on the
response of y2 and thus the integration step that is taken is controlled by y2 . In order to keep the
integrator from failing, very small step size need to be taken, leading to very long calculations
times of even the situation that the solver is unable to achieve the required accuracy.
Luckily, scilabs default and stiff solvers are specially designed to solve such systems of equations, rapidly, efficiently and accurately, in fact the default option automatically detects these
problems makes adjustments ot the solving routines.
5.2.2
Some higher order equations can be solved. Consider the second order ode,
1 d 2 C dC
+ kC = 0
P e dz 2
dz
letting y1 = C and y2 =
dC
yields
dz
1 dy2
y2 + ky1 = 0
P e dz
dy1
y2 = 0
dz
INTRODUCTION
33
and you end up with two odes, that can be solved using Scilab. This is a general approach for
any order, and works in scilab as long as the correct from can be obtained for all equations. The
initial values may not be immediately obvious or may only be avaliable at different positions, e.g.
one at z = 0 and the other at z = L. The equations can still be solved, but iteration is needed
to match the boundary conditions.
NOTE, there are better techniques for solving higher order odes, but these are not discussed
here.
6
6.1
34
Scilabs ode is has a number of options. The default solver is based on a BDF type extrapolation
solver that automatically decides between regular and stiff problems. What this means for you
is that
Scilabs ode solver can ONLY solve problems of the type
dy
= [f (t, y )]
dt
dy
where
can be a single of vector derivatives and [f (t, y )] can be a single equation or vector
dt
dy n
dy
or higher derivatives of n
of equations. [f (t, y )] cannot contain any terms which contain
dt
d t
n
dy
or multiples of
. It you have problems that do not look like this, you either have to
dt
massage them into this form, or you cannot solve them (there is another solver, dassl, that can
solve such systems, but we will not discuss its use here).
6.2
[ , atol ]] , f )
There are other options, but we will not discuss them here. The parameters in these solvers are
y The answer from the solver. For a single equation, it is a row vector y = [y (1), y (2), ...]
in which every element on y corresponds to a value in t (see below for t). For multiple equations, it depends on how you have defined the initial conditions. If is GOOD
PRACTICE (= YOUMUST USE
THIS WAY) to define the initial conditions as a coly 0(1)
y 0(2)
umn vector, y 0 =
and then y is returned as a row based matrix, y =
..
.
y (1, 1) y (1, 2)
y (2, 1) y (2, 2)
y 0 = [y 0(1),
with the data stored as fol y 0(2), ...], the y is returned as a row vector
lows, y = y (1, 1) y (2, 1) y (1, 2) y (2, 2) , basically a row vector, stacked
by row, and it will be very difficult to extract the data out of this vector into the matrix
form (it can be done using the matrix command).
[type] [optional] refers to the solver type to use, it has the following values: adams, stiff,
rk, rfk, fix. These will be discussed below. IT IS RECOMMENDED that you ignore
this setting and use the default solver. The default solver automatically chooses between
adams and stiff and should essentially solve all problems that you give it. If the default
solver fails, then with 99% certainty, your ODEs cannot be solved numerically.
35
y0 The initial conditions needed to solve the ODEs. y 0 is a vector of the same length as
the
number
of equations that you have. IT SHOULD BE A COLUMN VECTOR, y 0 =
y 0(1)
y 0(2)
.
..
.
t0 The time or position that corresponds to the initial conditions supplied in y 0. Generally iyt
has a value of zero, but this need not be the case, as long as t0 and y 0 are consistent,
then its OK.
t is a vector of time values at which the solution y will be calculated, starting at t0 and ending
at a user specified value or the size of the object or reactor. It is generally specified in
two ways, a linear progression of time steps, t=linspace(t0,tend,n) where tend is the user
specified end point and n is the number of values, thus
y (1, 1) y (1, 2)
t0 = t(1)
y (2, 1) y (2, 2)
t(2)
t=
; and corresponds to y =
..
..
..
.
.
.
y (n, 1) y (n, 2)
tend = t(n)
Typical values for n are between 50 and 100, enough to plot a smooth graph. In some
instances you may want to use less, say 10 or more, say 1000 to get better resolution
in a particular region. DO NOT specify values of n that are very big like 1000000, it is
not necessary and in some instances you may have to wait days for an answer. It is often
convenient (particularly in multi-reaction system) to specifiy the t vector using a log scale,
thus: t=logspace(tt0,ttend,n). However, TAKE NOTE OF THE FOLLOWING, the time
values refer to the powers of 10, thus the first time point is, t0 = 10tt0 and the last time
point is tend = 10ttend . logspace takes linear steps between tt0 and ttend, BUT the
ACTUAL time steps varying logarithmically between t0 = 10t0 and tend = 10tend . Also
note that the first time point is NOT ZERO and can never be zero, and it is thus necessary
to set t(1) = t0 = 0 in order for the time and initial conditions to be consistent. Thus
the time sequence will be
t(1) = t0 = 0
t(2) = 10tt(2)
tt(3)
t(2)
=
10
..
.
tt(n)=ttend
t(n) = 10
NOTE, that although the symbol t is used here as time, t simply refers to the independent
variable of the system, and thus it could refer to, reactor volumeV , reactor position Z,
residence time , length of the object L, distance travelled m, etc.
[rtol],[[atol]] [optional] These represent the relative (r tol ) and absolute (atol) in the values
of y . The error in y , element by element, is given by
y (i ) = r tol(i ) abs(y (i )) + atol(i )
The integration will continue as long as the error in all the elements of y meet the
requirements of the the y equation. To see how this works, consider two values of
y (i ) = [100, 103 ] and assume that atol = r tol = 104 . Then y (1) = 102 + 104
while y (2) = 107 + 104 . This shows that in the case of large values of y the relative
error, r tol, is important (first term) while for small values of y the absolute error, atol,
the second term is important. In this way integrators deal with with large and small
36
concentrations etc. If the integrator is unable to carry out the calculations that meet
this error requirement, the integrator will fail and report and error. r tol and atol can
be constants, in which case the same equation is applied to all y values, or they can be
vectors, in which the error will be different in each value of y . Although this is sometimes
useful, it will not be disucused further here. If you want to change atol and r tol IT IS
RECOMMENDED that you use them as constants. However, it is IMPORTANT TO
NOTE the default values of atol and r tol;
integrator option
default, adams, stiff, rk
rkf, fix
r tol
105
103
atol
107
104
It is recommended that you USE THE DEFAULT values, however, caution when comparing
rfk and fix to the others, you need to set the same error.
f this is the name of the function. It must have the form
f u n c t i o n y= f ( t , y )
// t i s a s i n g l e v a l u e
// y i s a c o l u m n v e c t o r , y = [ y ( 1 ) , y ( 2 ) , . . . . ]
// e q u a t i o n s h e r e
// a l l e q u a t i o n s t h a t d e p e n d on t and y MUST go i n h e r e
// f ( 1 ) = f 1 ( t , y )
// f ( 2 ) = f 2 ( t , y )
//.....
endfunction
The name of the function, f can be any valid scilab name, like pf r , cstr , er gun, kineti cs,
etc.
6.2.1
37
Now we are ready to execute the ode solver. It is called with the following command
y=ode ( y0 , z ( 1 ) , z , m o d e l )
Notice the transpose dash at the end of the line.
The output of the integrated values found in y , it is a column vector with 51 values of y which
correspond exactly with the values of z. These values can be printed to the console (or file) as
follows
p r i n t f ( \ n
p r i n t f ( % f
z
y \n ) ;
%f \n , z , y ) ;
Multi-equation example
= y1
= y1 y2
= y2 y3
= y3
38
y=ode ( y0 , t ( 1 ) , t , p f r )
The call is essentially the same as for the single equation.
The data can be printed to the console
p r i n t f ( \ n
p r i n t f ( % f
t
%f
%f
y1
%f
y2
%f \n , t , y )
y (1, 1)
t(1)
y (2, 1)
t(2)
t(3)
t=
; y = y (3, 1)
..
..
.
.
y (51, 1)
t(51)
y3
y4 \n )
y (1, 2)
y (2, 2)
y (3, 2)
..
.
y (1, 3)
y (2, 3)
y (3, 3)
..
.
y (1, 4)
y (2, 4)
y (3, 4)
..
.
7.1
A simple example
7.2
Applications
39
8.1
A simple example
8.2
8.3
Applications
40