A system of nonlinear equations is a system of equations comprising
at least one nonlinear equation. As no analytical solution can be found
in the majority of nonlinear systems, we have to approach those systems
numerically, for example by Bisection Method or Newton method. However,
Python enables the use of numerical solvers available in its libraries.
Those solvers are ready to be implemented with no additional knowledge
required. In this chapter, we will draw on sympy
library.
It could be installed by the command pip install sympy
.
Take, for instance, the equation 1/x = exp(x), see
Fig.1. We look for a value of x
that fulfills the given
equation.
import sympy as sm
= sm.Symbol("x", real=True)
x = sm.Eq(1 / x, exp(x))
equation = 0.5
init_val = sm.nsolve(equation, x, init_val)
solution print(solution)
If the program runs correctly, it prints the solution, approximately
0.5671
. We may assign the result to the variable
x
, in case we need to work with that value later on.
= solution x
Similarly, nsolve
enables solving systems of two or more
nonlinear equations. For example, let’s find the the intersections of a
unit circle placed at the origin of the coordinate system and a simple
sine wave, in the form of equations eq1
and
eq2
, see Fig.2.
from sympy import Symbol, Eq, nsolve
= Symbol("x", real=True)
x = Symbol("y", real=True)
y = [x, y]
unknowns
= Eq(x ** 2 + y ** 2 - 1, 0)
eq1 = Eq(y - sin(x), 0)
eq2 = [eq1, eq2]
equations
= [1, 1]
init_vals
= nsolve(equations, unknowns, init_vals)
sol print(sol)
If the program runs correctly, it prints the solution, approximately
0.7391
and 0.6736
. Again, we may assign the
result to the variables x
and y
, in case we
need to work with them later on.
= sol x, y
In case we choose the initial guess, for example,
[-1, -1]
, the program find the other solution,
corresponding to values -0.7391
and
-0.6736
.
In this section, we will solve a system of four equation containing four unknowns, originating from an engineering problem (Problem 15-6b in Chemical Engineering I, chapter Chemical Reactors).
Note that this problem deals with a design calculation, that is, we know both inlet and outlet parameters and the task is to find the number of reactors in a cascade of reactors in order to attain the required cummulative conversion of the input material.
First, we declare intermediate results from the problem 15-6a.
from sympy import Symbol, Eq, nsolve
= -2, 1, 1 # stoich coeffs
nuA, nuB, nuC = 5.0 # m3/kmol/h
k_plus = 0.3125 # m3/kmol/h
k_minus = 6.2745 # m3
V0 = 1.50, 0.0, 0.0 # kmol/m3
cA0, cB0, cC0 = 0.433, 0.533, 0.533 # kmol/m3
cAN, cBN, cCN = 0.062745 # h
tau_dash = 0.711 zetaAN
Now, we will perform the first iteration of the calculation, that is, we will calculate the cumulative conversion of N-1 reactor, with N denoting the last reactor in the cascade. This “backward-going” approach is advantageous as we avoid the need of solving a quadratic equation where the uknown is the cumulative conversion, possibly leading to the problem regarding which retured value is relevant for the task.
# Balance of A in the last reactor (N) in the cascade
= cAN - nuA * (k_plus * cAN ** 2 - k_minus * cBN * cCN) * tau_dash
cAN_1
= Symbol("cAN_2", real=True)
cAN_2= Symbol("cBN_1", real=True)
cBN_1 = Symbol("cCN_1", real=True)
cCN_1 = Symbol("zetaAN_1", real=True)
zetaAN_1
# Equations concering (N-1)th reactor
= Eq(cAN_2 - cAN_1 + \
eq1 * (k_plus * cAN_1 ** 2 - k_minus * cBN_1 * cCN_1) * tau_dash, 0)
nuA = Eq(cAN_1, cA0 * (1 - zetaAN_1))
eq2 = Eq(cBN_1, cB0 - nuB / nuA * cA0 * zetaAN_1)
eq3 = Eq(cCN_1, cC0 - nuC / nuA * cA0 * zetaAN_1)
eq4 = [eq1, eq2, eq3, eq4]
equations
= [cAN_2, cBN_1, cCN_1, zetaAN_1]
unknowns
= [cAN_1, cBN, cCN, zetaAN]
init_vals = nsolve(equations, unknowns, init_vals)
sol = sol
cAN_2, cBN_1, cCN_1, zetaAN_1 print(zetaAN_1)
The value of cummulative conversion in the (N-1)th reactor
should be 0.640
. Given that this value is positive, we must
analogously solve these equations in multiple iterations.