配平化学方程式¶
The latest version of this IPython notebook is available at http://github.com/jckantor/CBE20255 for noncommercial use under terms of the Creative Commons Attribution Noncommericial ShareAlike License.¶
J.C. Kantor (Kantor.1@nd.edu)
In [1]:
import sympy
sympy.var(['vCH4', 'vO2', 'vCO2', 'vH2O'])
atomBalances = [
sympy.Eq(vCH4 + vCO2,0), # Carbon 碳原子
sympy.Eq(4*vCH4 + 2*vH2O,0), # Hydrogen 氢原子
sympy.Eq(2*vO2 + +2*vCO2 + vH2O,0) # Oxygen 氧原子
]
for eqn in atomBalances:
print (eqn)
还有一种独特的方法:给反应指定一个basis. basis是一个额外的方程,用来指定其中一种物质的化学计量系数。我们不妨将甲烷的计量系数设为-1
In [2]:
basis = [sympy.Eq(vCH4,-1)]
for eqn in atomBalances + basis:
print (eqn)
sympy.solve(atomBalances + basis)
Out[2]:
例2 一个自燃反应¶
一个例子是由SpaceX公司开发的SuperDraco引擎使用的甲基肼(MMH)和氧化剂四氧化二氮的自燃反应。
未配平的反应式如下:
下面我们计算计量系数配平反应式。考虑如下问题:一千克燃料需要多少氧化剂?
In [3]:
# Identify unknown stoichiometric coefficients
sympy.var(['vCH6N2','vN2O4','vCO2','vNO','vH2O'])
# Atom balances
eqns = [
sympy.Eq(1*vCH6N2 + vCO2,0), # Carbon
sympy.Eq(6*vCH6N2 + 2*vH2O,0), # Hydrogen
sympy.Eq(4*vN2O4 + 2*vCO2 + vNO + vH2O,0), # Oxygen
sympy.Eq(2*vN2O4 + vNO,0) # Nitrogen
]
# Basis
eqns.append(sympy.Eq(vCH6N2,-1))
for eqn in eqns:
print (eqn)
soln = sympy.solve(eqns)
print ("\nStoichiometric Coefficients: ", soln)
mwN2O4 = 92.011
mwCH6N2 = 46.07
nCH6N2 = 1.0/mwCH6N2 # kg-mol of MMH
nN2O4 = (soln[vN2O4]/soln[vCH6N2])*nCH6N2 # kg-mol of N2O4
mN2O4 = mwN2O4*nN2O4 # kg of N2O4
print ("\n{0:7.3f} kilograms of N2O4 required per kilogram of CH6N2".format(mN2O4))
例3 一个水溶液中有电荷转移的反应¶
金属镉\(Cd\)溶解于浓硝酸,生成\(Cd^{2+}\)离子和一氧化氮\(NO\).
反应式如下:
观察两侧的电荷,这个反应式显然无法直接配平。
对于这类反应,我们需要考虑水和溶液中的离子。配平反应式,我们考虑下面的8种物质:
设8个计量系数。接下来写出原子守恒的约束条件(4个,对应4种原子),电荷守恒约束条件(1个),并将\(Cd\)的计量系数指定为1(指定basis,1个):
In [4]:
# Identify unknown stoichiometric coefficients
v = sympy.var(['vCd','vH2O','vHNO3','vNO','vCdpos2','vHpos','vOHneg','vNO3neg'])
# Atom balances
eqns = [
sympy.Eq(vCd + vCdpos2, 0), # Cadmium
sympy.Eq(2*vH2O + vHNO3 + vHpos + vOHneg, 0), # Hydrogen
sympy.Eq(vH2O + 3*vHNO3 + vNO + vOHneg + 3*vNO3neg, 0), # Oxygen
sympy.Eq(vHNO3 + vNO + vNO3neg, 0) # Nitrogen
]
# Charge balance
eqns.append(sympy.Eq(2*vCdpos2 + vHpos - vOHneg - vNO3neg, 0))
# Basis
eqns.append(sympy.Eq(vCd, -1))
for eqn in eqns:
print (eqn)
这里,变量数多于方程数,因此有一定的自由度(degrees of freedom)。我们需要做出额外的假设。
我们假设在浓硝酸中,硝酸完全电离,即有 \(\nu_{HNO_3}=0\).
我们假设在浓硝酸中,硝酸完全电离,即有 \(\nu_{HNO_3}=0\).
In [5]:
eqns.append(sympy.Eq(vHNO3, 0))
sympy.solve(eqns)
Out[5]:
其中6个计量系数已经确定,但还存在水和\(\nu_{OH^-}\)计量系数的依赖关系。考虑水的电离:
我们令 \(\nu_{H_2O} = 0\)
我们令 \(\nu_{H_2O} = 0\)
In [6]:
sympy.solve(eqns + [sympy.Eq(vH2O,0)])
Out[6]:
到此,给出了平衡的反应式: