{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# 配平化学方程式" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "###### The latest version of this IPython notebook is available at [http://github.com/jckantor/CBE20255](http://github.com/jckantor/CBE20255) for noncommercial use under terms of the [Creative Commons Attribution Noncommericial ShareAlike License](http://creativecommons.org/licenses/by-nc-sa/4.0/).\n", "\n", "J.C. Kantor (Kantor.1@nd.edu)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "### 例1 甲烷燃烧\n", "\n", "甲烷 (\\\\( CH_4\\\\) ) 燃烧的反应如下: \n", "\n", "$$ CH_4 + O_2 \\rightarrow CO_2 + H_2O $$\n", "\n", "我们要寻找一组计量系数来配平这个反应式。计量系数\\\\(\\nu_s\\\\)是一组和物质$s$ 对应的系数,使得反应式可以写成下面的形式:\n", "\n", "$$ \\nu_{CH_4}CH_4 + \\nu_{O_2}O_2 + \\nu_{CO_2}CO_2 + \\nu_{H_2O}H_2O = 0 $$\n", "\n", "负化学计量系数对应于反应物,正化学计量系数对应于该反应的产物。计量系数应使得反应前后各物质中原子守恒。如果反应中有带电物质,还应保证电荷守恒。\n", "\n", "计算计量系数可以使用 [SymPy](http://sympy.org/en/index.html) 包。 \n", "\n", "可以为参与反应的每种物质设一个计量系数,并用计量系数表示出原子守恒条件。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "vCH4 + vCO2 == 0\n", "4*vCH4 + 2*vH2O == 0\n", "2*vCO2 + vH2O + 2*vO2 == 0\n" ] } ], "source": [ "import sympy\n", "\n", "sympy.var(['vCH4', 'vO2', 'vCO2', 'vH2O'])\n", "\n", "atomBalances = [\n", " sympy.Eq(vCH4 + vCO2,0), # Carbon 碳原子\n", " sympy.Eq(4*vCH4 + 2*vH2O,0), # Hydrogen 氢原子\n", " sympy.Eq(2*vO2 + +2*vCO2 + vH2O,0) # Oxygen 氧原子\n", "]\n", "\n", "for eqn in atomBalances:\n", " print (eqn)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "还有一种独特的方法:给反应指定一个_basis_. basis是一个额外的方程,用来指定其中一种物质的化学计量系数。我们不妨将甲烷的计量系数设为-1" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "vCH4 + vCO2 == 0\n", "4*vCH4 + 2*vH2O == 0\n", "2*vCO2 + vH2O + 2*vO2 == 0\n", "vCH4 == -1\n" ] }, { "data": { "text/plain": [ "{vCO2: 1, vCH4: -1, vO2: -2, vH2O: 2}" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "basis = [sympy.Eq(vCH4,-1)]\n", "\n", "for eqn in atomBalances + basis:\n", " print (eqn)\n", "\n", "sympy.solve(atomBalances + basis)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 例2 一个自燃反应\n", "\n", "
\n", "\"Ball
\"Methylhydrazine-3D-balls\". Licensed under Public Domain via Wikimedia Commons.\n", "
\n", "自燃是一类自发产生的燃烧反应。自燃推进器是这类反应的一种常见应用。\n", "\n", "一个例子是由SpaceX公司开发的SuperDraco引擎使用的甲基肼(MMH)和氧化剂四氧化二氮的自燃反应。\n", "\n", "**未配平**的反应式如下:\n", "\n", "$$ CH_6N_2 + N_2O_4 \\rightarrow CO_2 + NO + H_2O $$\n", "\n", "下面我们计算计量系数配平反应式。考虑如下问题:一千克燃料需要多少氧化剂?" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "vCH6N2 + vCO2 == 0\n", "6*vCH6N2 + 2*vH2O == 0\n", "2*vCO2 + vH2O + 4*vN2O4 + vNO == 0\n", "2*vN2O4 + vNO == 0\n", "vCH6N2 == -1\n", "\n", "Stoichiometric Coefficients: {vCO2: 1, vH2O: 3, vCH6N2: -1, vN2O4: -5/2, vNO: 5}\n", "\n", " 4.993 kilograms of N2O4 required per kilogram of CH6N2\n" ] } ], "source": [ "# Identify unknown stoichiometric coefficients\n", "sympy.var(['vCH6N2','vN2O4','vCO2','vNO','vH2O'])\n", "\n", "# Atom balances\n", "eqns = [\n", " sympy.Eq(1*vCH6N2 + vCO2,0), # Carbon\n", " sympy.Eq(6*vCH6N2 + 2*vH2O,0), # Hydrogen\n", " sympy.Eq(4*vN2O4 + 2*vCO2 + vNO + vH2O,0), # Oxygen\n", " sympy.Eq(2*vN2O4 + vNO,0) # Nitrogen\n", "]\n", "\n", "# Basis\n", "eqns.append(sympy.Eq(vCH6N2,-1))\n", "\n", "for eqn in eqns:\n", " print (eqn)\n", "\n", "soln = sympy.solve(eqns)\n", "print (\"\\nStoichiometric Coefficients: \", soln)\n", "\n", "mwN2O4 = 92.011\n", "mwCH6N2 = 46.07\n", "\n", "nCH6N2 = 1.0/mwCH6N2 # kg-mol of MMH\n", "nN2O4 = (soln[vN2O4]/soln[vCH6N2])*nCH6N2 # kg-mol of N2O4\n", "mN2O4 = mwN2O4*nN2O4 # kg of N2O4\n", "\n", "print (\"\\n{0:7.3f} kilograms of N2O4 required per kilogram of CH6N2\".format(mN2O4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 例3 一个水溶液中有电荷转移的反应\n", "\n", "镉将在硝酸的浓溶液溶解以形成离子$镉^ {+2} $该生产自由基一氧化氮($ NO$)的。写一个平衡的反应。\n", "\n", "金属镉 ($Cd$)溶解于浓硝酸,生成$Cd^{+2}$离子和一氧化氮($NO$). \n", "\n", "反应式如下:\n", "\n", "$$Cd + NO_3^- \\longrightarrow Cd^{+2} + NO$$\n", "\n", "观察两侧的电荷,这个反应式显然无法直接配平。\n", "对于这类反应,我们需要考虑水和溶液中的离子。配平反应式,我们考虑下面的8种物质:\n", "\n", "$$Cd,\\ H_2O,\\ HNO_3,\\ NO,\\ Cd^{+2},\\ H^+,\\ OH^-,\\ NO_3^-$$\n", "\n", "设8个计量系数。接下来写出原子守恒的约束条件(4个,对应4种原子),电荷守恒约束条件(1个),并将$Cd$的计量系数指定为1(指定basis,1个):" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "vCd + vCdpos2 == 0\n", "2*vH2O + vHNO3 + vHpos + vOHneg == 0\n", "vH2O + 3*vHNO3 + vNO + 3*vNO3neg + vOHneg == 0\n", "vHNO3 + vNO + vNO3neg == 0\n", "2*vCdpos2 + vHpos - vNO3neg - vOHneg == 0\n", "vCd == -1\n" ] } ], "source": [ "# Identify unknown stoichiometric coefficients\n", "v = sympy.var(['vCd','vH2O','vHNO3','vNO','vCdpos2','vHpos','vOHneg','vNO3neg'])\n", "\n", "# Atom balances\n", "eqns = [\n", " sympy.Eq(vCd + vCdpos2, 0), # Cadmium\n", " sympy.Eq(2*vH2O + vHNO3 + vHpos + vOHneg, 0), # Hydrogen\n", " sympy.Eq(vH2O + 3*vHNO3 + vNO + vOHneg + 3*vNO3neg, 0), # Oxygen\n", " sympy.Eq(vHNO3 + vNO + vNO3neg, 0) # Nitrogen\n", "]\n", "\n", "# Charge balance\n", "eqns.append(sympy.Eq(2*vCdpos2 + vHpos - vOHneg - vNO3neg, 0))\n", "\n", "# Basis\n", "eqns.append(sympy.Eq(vCd, -1))\n", "\n", "for eqn in eqns:\n", " print (eqn)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这里,变量数多于方程数,因此有一定的_自由度(degrees of freedom)_。我们需要做出额外的假设。\n", "\n", "我们假设在浓硝酸中,硝酸完全电离,即有 $\\nu_{HNO_3}=0$." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{vHpos: vOHneg - 8/3,\n", " vNO: 2/3,\n", " vHNO3: 0,\n", " vH2O: -vOHneg + 4/3,\n", " vCd: -1,\n", " vCdpos2: 1,\n", " vNO3neg: -2/3}" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eqns.append(sympy.Eq(vHNO3, 0))\n", "sympy.solve(eqns)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "其中6个计量系数已经确定,但还存在水和 $\\nu_{OH^-}$ 计量系数的依赖关系。考虑水的电离:\n", "\n", "$$H_2O \\longrightarrow H^+ + OH^-$$\n", "\n", "我们令 $\\nu_{H_2O} = 0$" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{vHpos: -4/3,\n", " vOHneg: 4/3,\n", " vNO: 2/3,\n", " vHNO3: 0,\n", " vH2O: 0,\n", " vNO3neg: -2/3,\n", " vCdpos2: 1,\n", " vCd: -1}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sympy.solve(eqns + [sympy.Eq(vH2O,0)])\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "到此,给出了平衡的反应式:\n", "\n", "$$ Cd + \\frac{4}{3}\\,H^+ + \\frac{2}{3}\\,NO_3^- \\longrightarrow Cd^{+2} + \\frac{4}{3}\\,OH^- + \\frac{2}{3}\\,NO $$" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.0" }, "widgets": { "state": {}, "version": "1.1.2" } }, "nbformat": 4, "nbformat_minor": 1 }