Solving Nonlinear Systems#

Teng-Jui Lin

Content adapted from UW CHEME 375, Chemical Engineering Computer Skills, in Spring 2021.

  • Python skills and numerical methods

  • ChemE applications

    • Solving vapor-liquid equilibrium (VLE) problems

Solving binary vapor liquid equilibrium (VLE) problems#

Problem Statement. 1-propanol and 1-butanol are in binary vapor liquid equilibrium at a pressure of 0.5 atm. 1-propanol is 33% by moles in the liquid phase. Assuming ideal gas and solution behavior, determine the composition of the vapor phase and the temperature.

Solution. Assuming ideal behavior, Raoult’s law states that the partial pressure of one component is equal to the vapor pressure of the component times its liquid mole fraction

\[ P_i = y_i P = x_i P_i^*(T) \]

where the vapor pressure can be determined by Antoine’s equation

\[ \log P_i^*(T) = A - \dfrac{B}{T+C} \]

Note that Antoine’s equation may take different form and units when using different tabulated values.

Let 1-propanol be A and 1-butanol be B, we have the following equations, known, and unknown values.

Known values#

  • Units in Antoine’s equation

    • P [=] mmHg

    • T [=] deg C

  • Parameters of Antoine’s equation (FRB Table B.4)

Compound

A

B

C

Valid T Range

1-propanol (A)

7.74416

1437.686

198.463

60.2 - 104.6

1-butanol (B)

7.36366

1305.198

173.427

89.2 - 125.7

  • Known liquid composition

    • \(x_A = 33\%\) (1-propanol)

  • Known pressure

    • \(P = 0.5 \ \mathrm{atm}\)

Unknown variables#

  • Composition of liquid phase: \(x_B\)

  • Composition of vapor phase: \(y_A\), \(y_B\)

  • Temperature: \(T\)

Governing equations#

The raw equations are:

  • Raoult’s law and Antoine’s equation

    • \(y_A P = x_A P_A^*(T) = x_A 10^{\wedge}(A_A - \frac{B_A}{C_A+T})\)

    • \(y_B P = x_B P_B^*(T) = x_B 10^{\wedge}(A_B - \frac{B_B}{C_B+T})\)

  • conservation of mass (mole, since nonreactive)

    • \(y_A + y_B = 1\)

    • \(x_A + x_B = 1\)

Convert all the equations so they’re in the general form of \(F(x) = 0\):

  • Raoult’s law and Antoine’s equation

    • \(y_A P - x_A 10^{\wedge}(A_A - \frac{B_A}{C_A+T}) = 0\)

    • \(y_B P - x_B 10^{\wedge}(A_B - \frac{B_B}{C_B+T}) = 0\)

  • conservation of mass

    • \(1 - y_A - y_B = 0\)

    • \(1 - x_A - x_B = 0\)

We can now solve the four nonlinear equations with respect to the four unknown variables given the known values.

Implementation#

In this approach, we use scipy.optimize.fsolve() to solve the nonlinear system directly.

import numpy as np
from scipy.optimize import fsolve
def system(X, params):
    '''System of nonlinear equations'''
    # X -> unknown variables
    # params -> known values
    xb, ya, yb, T = X
    xa, P, Aa, Ba, Ca, Ab, Bb, Cb = params
    # set up system of equations of form F(x)=0
    eqns = np.array([
        ya*P - xa*10**(Aa - Ba/(Ca + T)),
        yb*P - xb*10**(Ab - Bb/(Cb + T)),
        1 - ya - yb,
        1 - xa - xb
    ])
    return eqns
# define known values
P = 0.5 * 760  # atm -> mmHg
xa = 0.33
params = [xa, P, 
          7.74416, 1437.686, 198.463,
          7.36366, 1305.198, 173.427]
# define initial guesses
X0 = [0.5, 0.5, 0.5, 100]
# solve the system using scipy.optimize.fsolve()
xb, ya, yb, T = fsolve(system, X0, params)
print(f'xb = {xb:.2f} mol butanol (l)/mol')
print(f'ya = {ya:.2f} mol propanol (v)/mol')
print(f'yb = {yb:.2f} mol butanol (v)/mol')
print(f'T = {T:.0f} deg C')
xb = 0.67 mol butanol (l)/mol
ya = 0.52 mol propanol (v)/mol
yb = 0.48 mol butanol (v)/mol
T = 91 deg C
# verify the root finding result
system([xb, ya, yb, T], params)
array([-6.07940365e-11, -4.01030320e-11, -5.55111512e-17,  0.00000000e+00])

The temprature of the system is 91 degrees Celcius, within the valid temperature range of the Antoine’s coefficients. The liquid phase mole fraction of 1-butanol is 67%. The vapor phase mole fraction of 1-propanol and 1-butanol are 52% and 48%, respectively.