This notebook contains course material from CBE20255 by Jeffrey Kantor (jeff at nd.edu); the content is available on Github. The text is released under the CC-BY-NC-ND-4.0 license, and code is released under the MIT license.
This Jupyter notebook demonstrate the use of the symbolic algebra package Sympy
for the generation/consumption analysis for the production of ammonia using basic principles of reaction stoichiometry.
BASF, headquartered in Ludwigshafen, Germany, is the largest chemical company in the world. In 1913, under its original name Badische Anilin- und Soda-Fabrik, BASF commercialized the Haber-Bosch process for the production of ammonia from natural gas, water, and air.
Prior to this invention, American and European agriculture was dependent on guano mined from the 'Guano Islands' in the Caribbean Sea and Pacific Ocean, and saltpeter mined from the deserts of Peru, Chile, and Bolivia. The competition for these limited resouces led to the notorious U.S. Guano Islands Act of 1856, and multiple wars (the Guano War, the War of the Pacific, later resulting in acute fertilizer shortages that was called 'the Wheat Problem' in England by Sir William Crookes in 1898.
The following video produced by BASF provides a technical overview of the Haber-Bosch process.
from IPython.display import YouTubeVideo
YouTubeVideo("uMkzxV_y7tY",560,315,rel=0)
Consider three reactions for the production of ammonia
Determine if it is possible to construct a process for the production of ammonia with no wasted hydrogen and no release of carbon monoxide.
We begin by setting up the stoichiometric matrix for generation/consumption analysis
Species | R1 | R2 | R3 | Net |
---|---|---|---|---|
χ1 | χ2 | χ3 | $\sum_k\nu_k\chi_k$ | |
CH4 | -1 | 0 | 0 | ≤ 0 |
H2O | -1 | -1 | 0 | ≤ 0 |
CO | 1 | -1 | 0 | 0 |
H2 | 3 | 1 | -3 | 0 |
CO2 | 0 | 1 | 0 | ≥ 0 |
N2 | 0 | 0 | 1 | ≤ 0 |
NH3 | 0 | 0 | 2 | 1 |
which includes three equality constraints which need to be solved for χ1, χ2, and χ3.
The first step is to import sympy
.
import sympy
When imported in this way, the functions from sympy
must be accessed with the prefix sympy.
. This avoids overwriting functions with the same name as those in sympy
, such as plot
.
Next we use the sympy.var
function to create three symbolic variables corresponding to χ1, χ2, and χ3.
sympy.var('x1 x2 x3')
(x1, x2, x3)
The net stoichiometric coefficients can be written in terms of the symbolic variables.
v = dict()
v['CH4'] = -x1
v['H2O'] = -x1 - x2
v['CO'] = x1 - x2
v['H2'] = 3*x1 + x2 - 3*x3
v['CO2'] = x2
v['N2'] = -x3
v['NH3'] = 2*x3
The three process constraints are encoded as equations using the sympy function Eq()
eqns = [
sympy.Eq(v['NH3'],1),
sympy.Eq(v['CO'],0),
sympy.Eq(v['H2'],0)
]
These equations are solved for χ1, χ2, and χ3.
soln = sympy.solve(eqns)
print(soln)
{x2: 3/8, x3: 1/2, x1: 3/8}
To finish the problem, the solutions are substituted back into the expressions for the stoichiometric coefficients, and the non-zero coefficients are displayed.
for k in v.keys():
a = v[k].subs(soln)
if a != 0:
print("{0:<3s} {1:>6s}".format(k,str(a)))
N2 -1/2 H2O -3/4 NH3 1 CH4 -3/8 CO2 3/8