You are on page 1of 6

5.

5 Complex Chemical Equilibrium by Gibbs Energy Minimization


5.5.1 Concepts Demonstrated
Formulation of the chemical equilibrium problem as Gibbs energy minimization
problem with atom balance constrains. The use of Lagrange multipliers to
introduce the constraints into the objective function. Conversion of the
minimization problem into a system of nonlinear algebraic equations.
5.5.2 Numerical Methods Utilized
Solution of a system of nonlinear algebraic equations with constrains
5.5.3 MATLAB Options, Commands and Functions Demonstrated
Use of the fsolve and conles functions for solving a system of nonlinear algebraic
equations with constrains.
5.5.4 Problem Definition
Rework Problem 4.5a using MATLAB:
(a) Obtain the MATLAB function generated by Polymath for this problem. Use
the MATLAB library function fsolve (from the initial estimates shown in Table
2 of Prob. 4.5) to solve the problem in order to obtain the Lagrange multiplier
values and the molar amounts of the various compounds at equilibrium.
(b) Use the constrained nonlinear algebraic equation solver: conles function to
solve the system of equations from the same initial estimates as in (a).
(c) Find the objective function value at the solution.
5.2.5 Solution
(a) The set of Polymath equations for this problem are shown in Table 2 of Prob.
4.5. In order to obtain the equation set arranged in the order calculation and
formatted as a MATLAB function the Polymath option "Show MATLAB
formatted problem in report" must be turned on. This option is accessible by
opening the icon marked as: "Setup preferences and numerical parameters". The
MATLAB formatted equation set is displayed in the Polymath report page
together with the solution results.
The resultant MATLAB function is shown in Table 1.
The conversion of the Polymath equation set (see Table 2 in Prob. 4.5) to the
MATLAB syntax involved the following main changes.
1. The function statement:
function fx=MNLEfun(x)
has been added as the first line of the function.

Table 1 MATLAB function generated by Polymath, for Problem 5.5


No.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

Command % Comment
function fx = MNLEfun(x);
lamda1 = x(1);
lamda2 = x(2);
lamda3 = x(3);
H2 = x(4);
H2O = x(5);
CO = x(6);
CO2 = x(7);
CH4 = x(8);
C2H6 = x(9);
C2H4 = x(10);
C2H2 = x(11);
O2 = x(12);
R = 1.9872;
sum = H2 + O2 + H2O + CO + CO2 + CH4 + C2H6 + C2H4 + C2H2;
fx(1,1) = 2 * CO2 + CO + 2 * O2 + H2O - 4; %Oxygen balance
fx(2,1) = 4 * CH4 + 4 * C2H4 + 2 * C2H2 + 2 * H2 + 2 * H2O + 6 * C2H6 - 14;
%Hydrogen balance
fx(3,1) = CH4 + 2 * C2H4 + 2 * C2H2 + CO2 + CO + 2 * C2H6 - 2; %Carbon balance
fx(4,1) = log(H2 / sum) + 2 * lamda2;
fx(5,1) = -46.03 / R + log(H2O / sum) + lamda1 + 2 * lamda2;
fx(6,1) = -47.942 / R + log(CO / sum) + lamda1 + lamda3;
fx(7,1) = -94.61 / R + log(CO2 / sum) + 2 * lamda1 + lamda3;
fx(8,1) = 4.61 / R + log(CH4 / sum) + 4 * lamda2 + lamda3;
fx(9,1) = 26.13 / R + log(C2H6 / sum) + 6 * lamda2 + 2 * lamda3;
fx(10,1) = 28.249 / R + log(C2H4 / sum) + 4 * lamda2 + 2 * lamda3;
fx(11,1) = C2H2 - exp(-(40.604 / R + 2 * lamda2 + 2 * lamda3)) * sum;
fx(12,1) = O2 - exp(-2 * lamda1) * sum;

2. The functions that are used for solving minimization problems or systems of
equations require passing the input arguments inside a single vector (x in this
case). The values stored in x are substituted into the local variables in a consistent
manner, thus commands like lamda1 = x(1) have been added.
3. The resultant function values must be stored in a single column vector (see lines
16-27 in Table 1).
To attempt the solution of this system of equations using the fsolve function the
"MultipleNLEtemplate.m" file shown in Table 2 (and available at Polymath's Help
section) can be used.
The MATLAB provided function fsolve is used to solve the system of nonlinear
equations. This function can be called with several different sets of input and
output parameters. The particular form used in Table 2 is:
xsolv=fsolve(@MNLEfun,xguess,options);
The first input parameter is the name of the function (MNLEfun) while the second
input parameter (xguess) is a vector of initial estimates for the values of the unknowns
at the solution. The options input parameter is a structure which contains parameters
associated with the solution method, error tolerances etc. A few of those parameters
are set by the options command shown in line 10 of Table 2.
2

Table 2 Template File "MultipleNLEtemplate.m" for Solving A System of


Nonlinear Algebraic Equations
No.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Equation % Comment
function Prob_5_5a
clear, clc, format short g, format compact
xguess = [10. 10. 10. 5.992 1. 1. 0.993 0.001 0.001 0.001 0.001 0.0001]; % initial guess
vector
disp('Variable values at the initial estimate');
fguess=MNLEfun(xguess);
disp(' Variable
Value Function Value')
for i=1:size(xguess,2);
disp([' x' int2str(i) '
' num2str(xguess(i)) '
' num2str(fguess(i))]);
end
options = optimset('Diagnostics',['off'],'TolFun',[1e-9],'TolX',[1e-9]);
xsolv=fsolve(@MNLEfun,xguess,options);
disp('Variable values at the solution');
fsolv=MNLEfun(xsolv);
disp(' Variable
Value Function Value')
for i=1:size(xguess,2);
disp([' x' int2str(i) '
' num2str(xsolv(i)) '
' num2str(fsolv(i))])
end

The parameter returned by the fsolve function is the vector of the values of the
unknowns at the solution (xsolv). The function fsolve uses minimization techniques
(such as the Levenberg Marguardt method with line search) in order to solve the
system of nonlinear equations.
The template file (of Table 2) and the function (in Table 1) are copied and pasted into
one file (Prob_5_5a.m) in order to run the program (note that the vector of initial
estimates xguess has been already introduced into the template file).
Running the program does not provide an acceptable solution but error messages,
such as " Optimization terminated: no further progress can be made. Problem may be
ill-conditioned". A potential cause for no convergence can be that there are errors
in the conversion of the function from Polymath to MATLAB.
To check this possibility the components of the vector f(x) calculated at the initial
estimate x0 (shown in Table 3) by MATLAB can be compared with the values
obtained by Polymath (shown also in Table 3). Note that in order to obtain f(x)
values in Polymath the option: "Calculate initial guess values" should be set at: true.
(this option can be found under the icon "Setup preferences and numerical
parameters" and "Nonlinear equations"). It can be seen that the values are essentially
the same, thus the Polymath to MATLAB conversion has been performed correctly
and the "no convergence" is caused by the inability of the solution algorithm to
handle this particular problem with the initial guesses provided.

Table 3. Initial variable: x and function: f(x) values obtained by Polymath and
MATLAB.
No
.
1
2
3

Variable
lamda1
lamda2
lamda3

Initial
value
10
10
10

H2

5.992

5
6
7

H2O
CO
CO2

1
1
0.993

CH4

0.001

C2H6

0.001

10
11
12

C2H4
C2H2
O2

0.001
0.001
0.0001

f(x)
Polymat
h
-0.0138
0
0
19.5944
1
4.64074
3
-6.32142
-19.8127
43.2160
8
84.0453
9
65.1117
1
0.001
1.00E-04

f(x)
MATLAB
-0.0138
0
0
19.5944
4.6407
-6.3214
-19.8127
43.2161
84.0454
65.1117
0.001
1.00E-04

(b) The conles function which is the MATLAB version of the same constrained
nonlinear algebraic equation solver algorithm1 that used by Polymath is used to
solve the constrained minimization problem. The function call of conles is:
[xsolv,y,dy,info]=conles(fun,xguess,pote,dfun,tol,maxit,derfun,print);
The input parameters are:
fun is a function which accepts input x and returns a column vector equation values f
evaluated at x
xguess is a vector of length n. It contains an estimate of the solution of the system of
equations. This initial estimate must satisfy the constraints.
pote is an vector of length n. It contains information on whether a given variable is
constrained or not. The value of the j-th component of pote is set as follows:
pote(j)= 0 - variable number j is not constrained, pote(j) = 1-a solution is sought
where x(j)>0 and pote(j) = 2 - x(j) must not obtain a value less than or equal to
zero during the solution process.
dfun (optional) is a function which accepts input x and returns an n*n matrix of
partial derivatives (Jacobian matrix)
tol is a nonnegative input variable. Convergence occurs if the euclidean norm of the
relative errors between two successive iterations is at most tol.
maxit is a positive integer input variable. Termination occurs if the number of
iterations is at maxit.
derfun is an logical input variable. Derfun = 1 (true) indicates that analytical
derivatives are being supplied by the user. Derfun = (0) false indicates that the
Jacobian matrix has to be approximated by divided differences.
1

Reference: Shacham, M., "Numerical Solution of Constrained Non-Linear Algebraic Equations",


International Journal of Numerical Methods in Engineering, 23, 1455-1481 (1986).

print is a logical variable which indicates whether printing of intermediate results is


required (print =1 ( true))
Output Parameters
xsolv is a vector of length n which contains the variable values at the solution.
y is a column vector of lenght n which contains the f (x) values at the solution.
dy is an nn square matrix which contains the partial derivatives at the solution
info is an integer variable set as follows: info = 0 - the Euclidean norm of the
relative errors between two successive iterates is at most tol in magnitude,
info = 1 - improper input parameters, info = 2 - initial estimate values do
not satisfy the constraints, info = 3 - number of iterations has reached maxit
and info = 4 or 5 - iteration is not making satisfactory progress or diverging.
To use the function conles instead of fsolve for solving this problem the template
file (of Table 2) must be modified by removing the call to fsolve (lines 10 and 11)
and inserting the following commands, instead:
10a
10b
10c
10d
10e
11

pote=[0 0 0 2 2 2 2 2 2 2 2 2];
tol=1e-9;
maxit=100;
derfun=0;
print=0;
[xsolv,y,dy,info]=conles(@MNLEfun,xguess,pote,[],tol,maxit,derfun,print);

In lines 10a through 10e the input parameter values (of the conles function) are set.
Note that all the variables, except the Lagrange multiplied are constrained to positive
values throughout the solution process (pote (j) = 2). No function for calculating the
matrix of partial derivatives is provided (derfun = 0 ).
In line 11 the conles function is called to solve the system of the constrained nonlinear
algebraic equations. Note that a space saver: [] is used instead of the 4 th parameter of
the function, as there is no function for calculating the matrix of partial derivatives.
The solution obtained is shown in Table 4. The variable and function values are
essentially the same that were obtained by Polymath (presented in Table 3 of Prob.
4.5)
Table 4. Solution obtained using the conles function
Variable values at the initial estimate
Variable
x1
x2
x3
x4
x5
x6
x7
x8
x9
x10
x11
x12

Value
10
10
10
5.992
1
1
0.993
0.001
0.001
0.001
0.001
0.0001

Function Value
-0.0138
0
0
19.5944
4.6407
-6.3214
-19.8127
43.2161
84.0454
65.1117
0.001
1.00E-04

Variable values at the solution


Function
Variable
Value
Value
x1
24.4197
0
x2
0.25306 -1.78E-15
x3
1.5598
0
x4
5.3452 -3.33E-16
x5
1.5216 -1.89E-15
x6
1.3885 -2.22E-16
x7
0.54492
6.88E-15
x8
0.066564
4.44E-16
x9
1.67E-07 -1.68E-13
x10
9.54E-08 -2.60E-13
x11
3.16E-10 -1.55E-25
x12
5.46E-21
3.88E-28

(c) To calculate the objective function (Eq.1 in Prob. 4.5) the commands shown in
Table 5 should be added following line 17 in Table 2. The objective function value (104.34) is the same as in the Polymath solution.
Table 5. MATLAB commands for calculating the Gibbs energy at the
solution.
No.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

Command % Comment
H2=xsolv(4);
H2O=xsolv(5);
CO=xsolv(6);
CO2=xsolv(7);
CH4=xsolv(8);
C2H6=xsolv(9);
C2H4=xsolv(10);
C2H2=xsolv(11);
O2=xsolv(12);
R = 1.9872;
sum = H2 + O2 + H2O + CO + CO2 + CH4 + C2H6 + C2H4 + C2H2;
G_O2 = O2 * log(abs(O2 / sum));
G_H2 = H2 * log(H2 / sum);
G_H2O = H2O * (-46.03 / R + log(H2O / sum));
G_CO = CO * (-47.942 / R + log(CO / sum));
G_CO2 = CO2 * (-94.61 / R + log(CO2 / sum));
G_CH4 = CH4 * (4.61 / R + log(abs(CH4 / sum)));
G_C2H6 = C2H6 * (26.13 / R + log(abs(C2H6 / sum)));
G_C2H4 = C2H4 * (28.249 / R + log(abs(C2H4 / sum)));
G_C2H2 = C2H2 * (40.604 / R + log(abs(C2H2 / sum)));
ObjFun = G_H2 + G_H2O + G_CO + G_O2 + G_CO2 + G_CH4 + G_C2H6 +
G_C2H4 + G_C2H2

You might also like