You are on page 1of 40

1

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

Systems of non-linear equations (NLEQs)

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 . . . . . . . . . . . . . . . . . . . . .

How to use Scilabs fsolve

Solving single equations


3.1 A simple example . . . . . . . . . . . . . . . . .
3.2 Finding multiple solutions . . . . . . . . . . . . .
3.3 Complex roots cannot be found . . . . . . . . .
3.4 Applications . . . . . . . . . . . . . . . . . . . .
3.4.1 Chemical equilibrium with single reaction
3.4.2 Flash calculation with 3 species . . . . .
3.4.3 CSTR with single reaction . . . . . . . .

II
5

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

Solving multiple equations


4.1 A simple example . . . . . . . . . . . .
4.2 Solving a linear system . . . . . . . . .
4.3 Applications . . . . . . . . . . . . . . .
4.3.1 Chemical equilibrium for multiple
4.3.2 Flash calculation . . . . . . . .
4.3.3 CSTR for 2 reactions . . . . . .

.
.
.
.
.
.
.

. . . . . .
. . . . . .
. . . . . .
reactions
. . . . . .
. . . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.

11
11
12
13
15
15
17
18

.
.
.
.
.
.

20
20
22
23
23
23
26

Ordinary differential equations

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

Solving single equations


7.1 A simple example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

39
39
39

Solving multiple equations


8.1 A simple example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.2 Solving a linear system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.3 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

40
40
40
40

Part I

Systems of non-linear equations (NLEQs)


1

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

An equation is termed non-linear when it is NOT POSSIBLE to write


x = an equation that does not contain x
Examples of non-linear equations are
ax 3 + bx 2 + cx + d = 0

(1)

a log(x) + b sin(x) c exp(x) + d = 0

(2)

Z 3 (1 B)Z 2 + (A 2B 3B 2 )Z (AB B 2 B 3 ) = 0

(3)

where A, B are given by




 0.5 2
ap
bp
A = 2 2; B =
; = 1 + 1 TTc
R T
RT
R2 Tc2
RTc
= 0.37464 + 1.54226 0.26992 ; a = 0.457235
; b = 0.077796
pc
pc
n
X Zi (Ki 1)
=0
1
+
(K
i 1)
i=1

2
FB0
3
FA0 X kCA0 V (1 X) FA0 X = 0


X FFB0
+
1

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

Arrangement of the equations for computer solution

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 equation, multiple solutions

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

Using the knowledge/features of the equation

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


..
..

.
.

vector, such that










Very important considerations about the solution of these systems


1. To have a chance of solving the equations, THE NUMBER OF EQUATIONS MUST
EQUAL THE NUMBER OF VARIABLES i.e. the number of fi 0 s must equal the xi0 s.
If this is not so a unique solution will NEVER be possible; thus THIS IS NECESSARY
CRITERION.
2. It is necessary that the equations are independent, in other no equation within the system
can be written as a combination of the other equations. With linear equations this is easily
shown, but for non-linear equations this is not always immediately obvious. Some checks
are made by the solver.
3. Just as in the case of single equations, there may be no solutions or there may be many
solutions. In other words, it is entirely possible that many combinations of xi0 s will all yield
F (X) = 0 or there may be NO set of xi0 s that achieve F (X) = 0.
4. The solution of non-linear equations requires and initial guess of the xi0 s, thus it is critical
that the user has good knowledge about the physical system that will ensure that right
the right initial guess is used to generate the physically realistic solution.
Here are some examples. Simple power terms can be arranged as follows;
a1 x + b1 y + c1 z + d1 = 0

(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

Another example using mathematical expressions;

a1 sin(x) + b1 cos(y ) + c1 tan(z) + d1 = 0

(11)

a2 log(x) + b2 log(y ) + c2 log(z) + d2 = 0

(12)

a3 exp(x) + b3 exp(y ) + c3 exp(z) + d3 = 0

(13)

Solving this system would be quite a challenge, if at all possible.


Considering systems closer to chemical engineering, 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; Overall mole balance;
F V L=0

(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;

the 3 phase equilibrium relations;

and the mole fraction summation equations;


(y1 x1 ) + (y2 x2 ) + (y3 x3 ) = 0

(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)

to be solved for (CA , CB , CC ).


The last example is looking at a constant pressure gas phase adiabatic CSTR
with volume V .

E
Consider a single reaction A B with reaction rate rA = k0 exp RT
CA . The mole and
energy balance is, assuming pure A with a flow rate of FA0 and temperature T0 ;
 

T0
E
FA0 X k0 exp RT CA0
(1 X) V = 0
T
HR X
T T0 +
=0
CP
There are 2 equations and the 2 unknowns are X and T and easily solved for (well not actually
since the exponential term on the rate constant, actually makes the system difficult to solve.
Look closely at the following equations
a1 log(x) + b1 exp(y ) + c1 z 2 + d1 = 0

(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.

HOW TO USE SCILABS FSOLVE

How to use Scilabs fsolve

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)

fsolve calculates these internally by numerical approximation (Phew!!!). However, if you


have a difficult system to solve, you can enter these by hand one at a time, Do not
enter these as a numerical approximation since fsolves internal methods are faster and far
superior to any user supplied procedure.
tol (optional) is the tolerance of the error of the 0 part of the equation, that is 0 shall be
less than tol. Typically tol is set at 1010 but in some instances 106 can be acceptable.
The function shall have the following structure for single equations

HOW TO USE SCILABS FSOLVE

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

SOLVING SINGLE EQUATIONS

3
3.1

11

Solving single equations


A simple example

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')

x from fsolve = 1.342923


x from roots = -2.813607 x from roots = 1.342923 x from roots = -0.529317

SOLVING SINGLE EQUATIONS

3.2

12

Finding multiple solutions

For the cubic equation f (x) = ax 3 + bx 2 + cx + d with a = 1, b = 2, c = 3 and d = 2, find


all the roots using Scilabs fsolve. Use Scilabs roots solver to cross check your answer.
solution
x from
x from
x from
x from
x from
x from
x from
x from
x from
x from
x from
x from
x from
x from
x from
x from
this
x from
x from
x from
x from
x from

fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve
fsolve

= 1.342923 starting from initial guess 1.000000


= -0.529317 starting from initial guess -1.000000
= -2.813607 starting from initial guess -3.000000
= -2.813607 starting from initial guess -10.000000
= -2.813607 starting from initial guess -9.000000
= -2.813607 starting from initial guess -8.000000
= -2.813607 starting from initial guess -7.000000
= -2.813607 starting from initial guess -6.000000
= -2.813607 starting from initial guess -5.000000
= -2.813607 starting from initial guess -4.000000
= -2.813607 starting from initial guess -3.000000
= -2.813607 starting from initial guess -2.000000
= -0.529317 starting from initial guess -1.000000
= -0.529317 starting from initial guess 0.000000
= 1.342923 starting from initial guess 1.000000
= 1.342923 starting from initial guess 2.000000it is more difficult recognise that

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

SOLVING SINGLE EQUATIONS

from
from
from
from
from

13

fsolve = 1.342923 starting from initial guess 8.000000


fsolve = 1.342923 starting from initial guess 9.000000
roots = -2.813607
roots = 1.342923
roots = -0.529317

//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 all the roots 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
//the way to find all the roots is to change the initial guess
//this can either be done by hand
printf('\n')
x0=1 //initial guess
x=fsolve(x0,model)
printf('x from fsolve = %f starting from initial guess %f\n',x,x0)
x0=-1 //initial guess
x=fsolve(x0,model)
printf('x from fsolve = %f starting from initial guess %f\n',x,x0)
x0=-3 //initial guess
x=fsolve(x0,model)
printf('x from fsolve = %f starting from initial guess %f\n',x,x0)
//or if you do not know the answer as in this case, you can execute fsolve
//in a loop
printf('\n')
x0=-11
for i=1:20
x0=x0+1
x=fsolve(x0,model)
printf('x from fsolve = %f starting from initial guess %f\n',x,x0)
end
//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\n',xsolution)

3.3

Complex roots cannot be found

Solve the cubic equation for its root f (x) = ax 3 + bx 2 + cx + d with a = 1, b = 1, c = 3


and d = 2 find all the roots. 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.

SOLVING SINGLE EQUATIONS

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')

x from fsolve = -0.720460 error in f(x) = -0.731646 status of fsolve = 4


x from fsolve = 2.511547 error in f(x) = -0.000000 status of fsolve = 1
x from fsolve = 2.511547 error in f(x) = -0.000000 status of fsolve = 1
x from roots = 2.511547 + 0.000000 i

14

SOLVING SINGLE EQUATIONS

15

x from roots = -0.755774 + 0.474477 i


x from roots = -0.755774 + -0.474477 i

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

SOLVING SINGLE EQUATIONS

X = 0.833333 at a pressure of 10.000000

//Solving the chemical equilibrium equation for conversion


//for the reation A+B = C,
// f(X)=Kp*Pt*(1-X)*(Fb0/Fa0-X)-X*(Fb0/Fa0-X)=0
// $$f(X)=K_pP_t(1-X)(F_{B0}/F_{A0}-X)-X(F_{B0}/F_{A0}-X)=0 $$
//finding a single root using fsolve
clear;clc
//define the function
Fa0=1
Fb0=1
Kp=0.5
Pt=10
function f=model(X)
f=Kp*Pt*(1-X)*(Fb0/Fa0-X)-X*(Fb0/Fa0-X)
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 pressure and calculate conversion as a function
//of volume by solving this equation repeatedly
dP=1
Pt=0
printf('\n')
for i=1:10
Pt=Pt+dP
//the pressure is changed here at each interation. It is very important that
//the variable used here, the Pt, is exactly the same as the variable used
//in the function, case sensitive.
//The variable Pt 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 pressure of %f\n',X,Pt)
//to plot the data, need to store the values of Pt and X in vectors
//thus
P(i)=Pt
Xr(i)=X
end
scf(1);clf
plot(P,Xr,'-ored')

16

SOLVING SINGLE EQUATIONS

3.4.2

17

Flash calculation with 3 species

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)

SOLVING SINGLE EQUATIONS

3.4.3

18

CSTR with single reaction

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 from fsolve = 0.317672


error in f(x) = 0.000000
status of fsolve = 1
X = 0.078301 at a volume of 0.100000
X = 0.170949 at a volume of 0.300000

X
X
X
X
X
X
X
X

SOLVING SINGLE EQUATIONS

=
=
=
=
=
=
=
=

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

SOLVING MULTIPLE EQUATIONS

4
4.1

20

Solving multiple equations


A simple example

Solve the system of equations for all possible solutions


f1 = 2x + 3y + 4z 1
f2 = 10x 2 y 2 + 2z 1
f3 = x 2y + 10
Use various starting guesses to see if there is more than one solution. Use [1 1 1] is the first
guess.
Solution
x = 2.218168
y = 6.109084
z = -5.440897
error vector for
error vector for
error vector for
info = 1
x = -1.525861
y = 4.237070
z = -2.164872
error vector for
error vector for
error vector for
info = 1
x = -1.525861
y = 4.237070
z = -2.164872
error vector for
error vector for
error vector for
info = 1
x = -1.525861
y = 4.237070
z = -2.164872
error vector for
error vector for
error vector for
info = 1
x = 2.218168
y = 6.109084
z = -5.440897
error vector for
error vector for
error vector for
info = 1

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

SOLVING MULTIPLE EQUATIONS

//Solving multiple equations


// f1=2*x+3*y+4*z-1
// f2=10*x^2-1*y^2+2*z-1
// f3=x-2*y+10
//
clear;clc
//define the function
function f=model(a)
x=a(1)
y=a(2)
z=a(3)
f1=2*x+3*y+4*z-1
f2=10*x^2-1*y^2+2*z-1
f3=x-2*y+10
f=[f1;f2;f3]
endfunction
a0=[1 1 1] //initial guess
[a,v,info]=fsolve(a0,model)
printf('\n')
printf('x = %f\n',a(1))
printf('y = %f\n',a(2))
printf('z = %f\n',a(3))
printf('error vector for f1 = %f\n',v(1))
printf('error vector for f2 = %f\n',v(2))
printf('error vector for f3 = %f\n',v(3))
printf('info = %i\n',info)
a0=[1 100 1] //initial guess
[a,v,info]=fsolve(a0,model)
printf('\n')
printf('x = %f\n',a(1))
printf('y = %f\n',a(2))
printf('z = %f\n',a(3))
printf('error vector for f1 = %f\n',v(1))
printf('error vector for f2 = %f\n',v(2))
printf('error vector for f3 = %f\n',v(3))
printf('info = %i\n',info)
a0=[-1 1 1] //initial guess
[a,v,info]=fsolve(a0,model)
printf('\n')
printf('x = %f\n',a(1))
printf('y = %f\n',a(2))
printf('z = %f\n',a(3))
printf('error vector for f1 = %f\n',v(1))
printf('error vector for f2 = %f\n',v(2))
printf('error vector for f3 = %f\n',v(3))
printf('info = %i\n',info)
a0=[-1 -1 -1] //initial guess
[a,v,info]=fsolve(a0,model)
printf('\n')
printf('x = %f\n',a(1))
printf('y = %f\n',a(2))
printf('z = %f\n',a(3))
printf('error vector for f1 = %f\n',v(1))
printf('error vector for f2 = %f\n',v(2))
printf('error vector for f3 = %f\n',v(3))
printf('info = %i\n',info)
a0=[0 0 0] //initial guess
[a,v,info]=fsolve(a0,model)
printf('\n')
printf('x = %f\n',a(1))
printf('y = %f\n',a(2))
printf('z = %f\n',a(3))
printf('error vector for f1 = %f\n',v(1))
printf('error vector for f2 = %f\n',v(2))
printf('error vector for f3 = %f\n',v(3))
printf('info = %i\n',info)

21

SOLVING MULTIPLE EQUATIONS

4.2

Solving a linear system

Consider the linear system,


f1 = 2x + 3y + 4z 1
f2 = 10x y + 2z 1
f3 = x 2y + 10
Solve this system using the non-linear solver and check the answer using a linear solver
Solution
solution using non-linear solver
x = 1.677419
y = 5.838710
z = -4.967742
error vector for f1 = 0.000000
error vector for f2 = -0.000000
error vector for f3 = 0.000000
info = 1
solution using linear solver
x = 1.677419
y = 5.838710
z = -4.967742

//Solving multiple equations when they linear


// f1=2*x+3*y+4*z-1
// f2=10*x-1*y+2*z-1
// f3=x-2*y+10
//
clear;clc
//define the function
function f=model(a)
x=a(1)
y=a(2)
z=a(3)
f1=2*x+3*y+4*z-1
f2=10*x-1*y+2*z-1
f3=x-2*y+10
f=[f1;f2;f3]
endfunction
a0=[1 1 1] //initial guess
[a,v,info]=fsolve(a0,model)
printf('\n')
printf('\nsolution using non-linear solver\n')
printf('x = %f\n',a(1))
printf('y = %f\n',a(2))
printf('z = %f\n',a(3))
printf('error vector for f1 = %f\n',v(1))
printf('error vector for f2 = %f\n',v(2))
printf('error vector for f3 = %f\n',v(3))
printf('info = %i\n',info)
//Linear solver, Ax=b
//finding x using backslash, x=A\b
A=[2 3 4;10 -1 2;1 -2 0]
b=[1 1 -10]'
x=A\b
printf('\nsolution using linear solver\n')
printf('x = %f\n',x(1))
printf('y = %f\n',x(2))
printf('z = %f\n',x(3))

22

SOLVING MULTIPLE EQUATIONS

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

//Solving the chemical equilibrium equations for conversion


//for the reations A = B, B = C,
// f1=Kab*Ca-Cb=0
// f2=Kbc*Cb-Cc=0
// f3=Ca0-ca-Cb-Cc=0
//
clear;clc
//define the function
Ca0=1
Kab=0.5
Kbc=2
function f=model(C)
Ca=C(1)
Cb=C(2)
Cc=C(3)
f1=Kab*Ca-Cb
f2=Kbc*Cb-Cc
f3=Ca0-Ca-Cb-Cc
f=[f1;f2;f3]
endfunction
C0=[0.8 0.1 0.1]' //initial guess, little more difficult
[C,v,info]=fsolve(C0,model)
printf('\n')
printf('C from fsolve = %f\n',C)
printf('error in f(x) = %f\n',v)
printf('status of fsolve = %i\n',info)

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

SOLVING MULTIPLE EQUATIONS

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

//define the function


F=1
Z=[0.3 0.4 0.3]'
K=[0.5 1.1 2]'
//you can formula the function using vector calculations
function f=model(X)
//X is now a vector comprised of the following 8 elements
//X=[V y1 y2 y3 x12 x2 x3 L]'
V=X(1)
y=X(2:4)
x=X(5:7)
L=X(8)
f1=F-V-L
f2=F*Z-V*y-L*x
f3=y-K.*x
f4=sum(x-y)
f=[f1;f2;f3;f4]
endfunction
//you can formulate the equations using a loop with term by term
addition
function f=model1(X)
//X is now a vector comprised of the following 8 elements
//X=[V y1 y2 y3 x12 x2 x3 L]'
V=X(1)
y=X(2:4)
x=X(5:7)
L=X(8)
f1=F-V-L
f2(1:3)=0;f3(1:3)=0;f4=0
for i=1:3
f2(i)=F*Z(i)-V*y(i)-L*x(i)
f3(i)=y(i)-K(i)*x(i)
f4=f4+(x(i)-y(i))
end
f=[f1;f2;f3;f4]

//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)

//initial guess is much more tricky, the best way is to assume


psi=0.5 and
//estimate V,L,x,y
psi=0.5
V=F*psi
L=F-V
x=Z./(1+psi*(K-1))
y=K.*x

endfunction
//now you can see the real reason for getting to understand how
scilab uses
//vector calculations

4
SOLVING MULTIPLE EQUATIONS
25

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

SOLVING MULTIPLE EQUATIONS

4.3.3

26

CSTR for 2 reactions

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

SOLVING MULTIPLE EQUATIONS

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

SOLVING MULTIPLE EQUATIONS

//Solving the CSTR design equation for conversion


//more than one reaction
//for the reactions A = B and B = C
//ra=-k1*Ca^2, rb=k1Ca^2-k2Cb, rc=k2Cb
// f(X)=Ca0 - Ca-k1*V*Ca^2/v0
=0
// f(X)=
- Cb+k1*V*Ca^2/v0 - k2*V*Cb/v0 =0
// f(X)=
- Cc
+ k2*V*Cb/v0 =0
//
clear;clc
//define the function
Fa0=1
k1=1
k2=1
V=1
Ca0=1
v0=1
function f=model(C)
Ca=C(1)
Cb=C(2)
Cc=C(3)
f1=Ca0 - Ca-k1*V*Ca^2/v0
f2=
- Cb+k1*V*Ca^2/v0 - k2*V*Cb/v0
f3=
- Cc
+ k2*V*Cb/v0
f=[f1;f2;f3]
endfunction
C0=[Ca0/2 Ca0/4 Ca0/4]' //initial guess, this is not so easy here
//C0=[0.5 0.5 0.5]'
[C,v,info]=fsolve(C0,model)
printf('\n')
printf('C(%1i) from fsolve = %f\n',(1:3)',C)
printf('error in f(%1i) = %f\n',(1:3)',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
[C,v,info]=fsolve(C0,model)
printf('C(%1i) = %f at volume %f \n',(1:3)',C,V*[1 1 1]')
printf('\n')
//to plot the data, need to store the values of V and X in vectors
//thus
Vr(i)=V
Xr(i)=1-C(1)/Ca0
end
scf(1);clf
plot(Vr,Xr,'-ored')

28

29

Part II

Ordinary differential equations


5

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

The equation has to be of the form


dy
= f (t, y )
dt
dy
where the left hand side contains ONLY the derivative ( ) and the left hand side contains
dt
only constants and variables that depend on t and y . Also, you are solving for 1 variable, y as
a function of t, and thus there will be exactly ONE differential equation.
Some examples are
dy
= y
dx
dT (z)
= (Tw all (z) T (z))
dz
dy
2xy 2 + 2
= 2
dx
2x y + 4y
dxA
NA
NB
=
(1 xA (1 + )) , =
dz
cDAB
NA
p
dh
R2
= Qin A 2gh
dt
dCA

= 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

Arrangement of the equations for computer solution

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

Using the knowledge/features of the equation

Consider these two equations,


dy2
dy1
= 2y1 ,
= 2y2
dt
dt
The values of y1 will eventually stabilise at y1 () = 0, the solution is y1 = y0 exp(2t).
However, the values of y2 will continue to grow to inifnity, thus y2 () = , the solution is
y2 = y0 exp(2t), and thus this represents and unbounded and unstable problem. If one of your
equations has such features then the integrator will fail after a set number of time has elapsed.
Consider the equation
1X
dX
=k
dt
X
where X is the conversion and the product slows the reaction down and yields the X in the
denominator. This system cannot be solved by starting with zero conversion - some product
must be present in the reactor at t = 0. Often this is a feature of poorly derived kinetic
equations. The same argument can be applied to
dX
= k(1 X)X
dt
in which product must be present for the reaction to start.
Consider the equation
dC
= k
dt
the so called zero order rate equation. If C was a species cocentration, then after some time it
will go negative, again often the result of poorly derived kinetics.

5.2

Systems of equations

A simple example
dy1
= y1 t y2
dt
dy2
= y2 t y1
dt

INTRODUCTION

31

The orbital mechanics for the two body problem yields


dvx
dt
dx
dt
dvy
dt
dy
dt

GMx
(x 2 + y 2 )3/2

= vx
=

GMy
(x 2 + y 2 )3/2

= vy

double pipe heat exchanger


dTi
+ i (Ti T0 ) = 0
dx
dT0
0 (Ti T0 ) = 0
dx
Ud
Ud
, 0 =
where i is inside and 0 is outside.
Wi Cpi
W0 Cp0
Reaction with pressure drop in packed bed reactor


dX
k
1X
P
=
dW
FA0 1 + X P0
dP

= (1 + X)
dW
P

with i =

Reaction with temperature change in a adiabatic batch reactor;


dCA
E
= CAn k0 exp( RT
)
dt
dT
E
)
= HR CAn k0 exp( RT
mCP
dt
The single reaction system, A + B  C can be solved without first converting the system to
conversions via a stoichiometric table. In a gas phase PFR this yields
"
#

2
FA F B
P
FC
P
dFA
= k

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

These equations can quickly become comples


Unsteady state CSTRS in series, expanding the above equation for 3 CSTRS yields
dCA,1
n
= CA0 CA,1 kCA,1
dt
dCA,2
n
2
= CA,1 CA,2 kCA,2
dt
dCA,3
n
3
= CA,2 CA,3 kCA,3
dt
1

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

Solving higher order eqations

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.

HOW TO USE SCILABS ODE

6
6.1

34

How to use Scilabs ode


The form of the equations

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

The scilab command

The simplest Scilab command to start the solver is


y = ode ( y0 , t0 , t , f )
and the most complex command to start the solver that you might need is
y = ode ( [ t y p e , ] y0 , t0 , t [ , r t o l

[ , 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)

. If you have defined the initial conditions as a row vector,


..
..
.
.

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.

HOW TO USE SCILABS ODE

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

HOW TO USE SCILABS ODE

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

Single equation example

Consider the differential equation


dy
= 3.2 (100 y )
dz
The function that is needed is
f u n c t i o n f =m o d e l ( z , y )
f =3.2(100 y )
endfunction
dy
Notice that in the function f =
.
dz
The next step needed to define the range of z values over which the equations is to be solved
and number of point sthat are needed for the solution. The following command does that;
z= l i n s p a c e ( 0 , 1 , 5 1 )
It defines z as a column vector starting at 0 and ending at 1 with 51 equally spaced values between
0 and 1 (notice the transpose dash at the end of the line), thus z = [0, 0.02, 0.04, ..., 0.98, 1]0
The next step is to specify the initial condition. That means the value of y at the very first z
value needs to be specified, thus at z(1) = 0 the value of y will be y (1) = 25. The following
command does that
y0 =25

HOW TO USE SCILABS ODE

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 ) ;

or they can be plotted (the better option)


scf (1); clf
p l o t (z , y , blue )
6.2.2

Multi-equation example

Consider the the 4 simultaneous odes


dy1
dt
dy2
dt
dy3
dt
dy4
dt

= y1
= y1 y2
= y2 y3
= y3

The function required to solve this system is


f u n c t i o n f = p f r (V , y )
f (1)= y ( 1 )
f ( 2 ) = y (1) y ( 2 )
f ( 3 ) = y (2) y ( 3 )
f (4)= y (3)
endfunction
Notice that there are 4 variables, and thus y will be a column vector with 4 elements, y =
[y1 , y2 , y3 , y4 ]0 and thus there are also 4 equations and thus f is a column vector with 4 elements,
f = [f (1), f (2), f (3), f (4)]0 .The next steps follow much the same as for one equation.
The next step is to define the range of time values,t, over which the integration needs to take
place. For this the following command is used
t= l i n s p a c e (0 ,10 ,51)
Again this is 51 equally spaced points starting at 0 and ending at 10. t is a column vector.
The next step is to define the initial conditions of the equation system - this should always be
clear from the physics of the system. NOTE, we have 4 variables (values of y ), thus we need
to specify the values of ALL 4 elements of y that correspond to the first time point, t(1) = 0.
This is done use the following command
y0 = [ 1 0 0 0 ]
NOTICE, ITS VERY IMPORTANT to specify these as a column vector in order to get the
output in a easier to use format. Here we have specified that the value of y (1) = y1 = 1 and
the value of all the other y values are zero
The next step is the execute the solver

HOW TO USE SCILABS ODE

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 )

This command only produces a table when t is a


changes with t going down the column, thus

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 )

column vector AND the values in y reflect the

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)
..
.

y (51, 2) y (51, 3) y (51, 4)

or the data can be plotted (preferred for data like this)


scf (1); clf
plot (t , y)
The beauty of the plot command is that it automatically color codes the lines.

SOLVING SINGLE EQUATIONS

Solving single equations

7.1

A simple example

7.2

Applications

39

SOLVING MULTIPLE EQUATIONS

Solving multiple equations

8.1

A simple example

8.2

Solving a linear system

8.3

Applications

40