{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Combustion stoichiometry\n",
    "\n",
    "* Combustion occurs between Fuel and Air (or oxidizer)\n",
    "* Need to get the mixing ratio / stoichiometry right."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Air properties\n",
    "\n",
    "* Use $x$ for mole fraction, and $y$ for mass fraction.\n",
    "\n",
    "|  species|     x     |      y   |\n",
    "|---------|:---------:|:--------:|\n",
    "| N$_2$   | 0.7809    |  0.75532 |\n",
    "| O$_2$   | 0.2095    |  0.23144 |\n",
    "| Ar      | 0.0096    |  0.01324 |\n",
    "\n",
    "* Lump Ar with N$_2$:\n",
    "\n",
    "| species |     x     |      y   |\n",
    "|---------|:---------:|:--------:|\n",
    "| **N$_2$**   | **0.79**    |  **0.77**   |\n",
    "| **O$_2$**   | **0.21**    |  **0.23**   |\n",
    "\n",
    "* **n$_{N2}$/n$_{O2}$  = 3.76**\n",
    "* **n$_{air}$/n$_{O2}$ = 4.76**\n",
    "\n",
    "\n",
    "## Mean molecular weight\n",
    "\n",
    "* M = 28.96 kg/kmol\n",
    "* **M = 29 kg/kmol**\n",
    "\n",
    "$$ (M) = \\sum_k x_k (M_k),$$\n",
    "$$ \\left(\\frac{1}{M}\\right) = \\sum_ky_k\\left(\\frac{1}{M_k}\\right).$$\n",
    "$$ \\phantom{xxxxxx}\\rightarrow M = \\frac{1}{\\sum_k \\frac{y_k}{M_k}}.$$\n",
    "\n",
    "* Intuitively, for $M$ in terms of $x_k$\n",
    "    * $(M)$ has units of kg/kmol.\n",
    "    * For a basis of 1 total kmol, the $x_k$ are the kmol of each species.\n",
    "    * Then $x_kM_k$ is the kg of each species.\n",
    "    * Sum these up and we have the total kg, with 1 kmol assumed, so the sum is M.\n",
    "* Similarly, for $M$ in terms of $y_k$\n",
    "    * Work with (1/M) with units of kmol/kg\n",
    "    * For a basis of 1 total kg, the $y_k$ are the kg of each species.\n",
    "    * Then $y_k(1/M_k)$ is the kmol of each species.\n",
    "    * Sum these up and we have the total kmol, with 1 kg assumed, so the sum is (1/M).\n",
    "\n",
    "## Convert $x_k$ to $y_k$\n",
    "\n",
    "$$ x_kM_k = y_kM.$$\n",
    "\n",
    "To remember this, we have a form that looks like $xM=yM$. $x$ comes before $y$ in the alphabet. Then group the $k$ subscripts together on the first three terms.\n",
    "\n",
    "Solve for $x_k$ and $y_k$ as needed:\n",
    "$$ y_k = \\frac{x_kM_k}{M},$$\n",
    "$$ x_k = \\frac{y_kM}{M_k}.$$\n",
    "\n",
    "If you want to derive the equation. Start with $y_k$, say, and get $x_k$:\n",
    "* $y_k$ is $m_k/m_t$, ($t$ for total).\n",
    "* Then convert this to $x_k$, which is $n_k/n_t$.\n",
    "* Change the $m_k$ to $n_k$ by dividing by $M_k=m_k/n_k$:\n",
    "    * $y_k/M_k = \\frac{m_k}{m_t}\\frac{n_k}{m_k} = \\frac{n_k}{m_t}$\n",
    "* Similarly, change the $m_t$ to $n_t$ by multiplying by $M=m_t/n_t$.\n",
    "* The result is $x_k = y_k\\frac{M}{M_k}$.\n",
    "* Then can solve for $y_k$ to get $y_k = x_k\\frac{M_k}{M}$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Stoichiometry\n",
    "\n",
    "* Rich (too much fuel)\n",
    "* Lean (too much air)\n",
    "* Stoichiometric (just right)\n",
    "\n",
    "### Air-to-fuel ratio\n",
    "$$ \\frac{A}{F} = \\frac{m_{air}}{m_{fuel}}.$$\n",
    "\n",
    "* Mass Basis\n",
    "* $0 \\le A/F \\le \\infty$\n",
    "\n",
    "### Equivalence ratio\n",
    "$$\\Phi = \\frac{F/A}{(F/A)_{stoic}}$$\n",
    "* Mass or mole basis (same).\n",
    "* $0 \\le \\Phi \\le \\infty$\n",
    "* $\\Phi=0$ is lean, $\\Phi>1$ is rich.\n",
    "* $\\Phi$ is common in practical applications.\n",
    "\n",
    "### Mixture fraction\n",
    "$$\\xi = \\frac{m_f}{m_f + m_a}$$\n",
    "* Notation, $\\xi$, or $f$, or $Z$ is common.\n",
    "* $0\\le \\xi\\le 1$\n",
    "* $\\xi=0$ is pure air, $\\xi=1$ is pure fuel.\n",
    "* $\\xi$ is common in modeling.\n",
    "* $\\xi$ can be defined in terms of any two distinct streams, not just fuel and air.\n",
    "\n",
    "### Ideal gas law\n",
    "* $PV = nRT$\n",
    "* Solve for $n$ and divide by $V$, with $n/V = c$, that is molar concentration:\n",
    "    * $c = P/RT$\n",
    "* Multiply through by $M$, with $\\rho=cM$, that is, mass density:\n",
    "    * $\\rho = MP/RT$\n",
    "* Here, $R$ is the gas constant, $R=8314.46$ J/kmol$\\cdot$K."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Balanced reactions \n",
    "\n",
    "### Methane combustion\n",
    "\n",
    "* Normally write 1 mole of fuel for convenience.\n",
    "* 1 mole O$_2$ gives 4.75 moles Air = O$_2$ + 3.76 N$_2$.\n",
    "* Mole basis\n",
    "* Products\n",
    "    * Carbon $\\rightarrow$ CO$_2$\n",
    "    * Hydrogen $\\rightarrow$ H$_2$O\n",
    "\n",
    "$$(CH_4) + \\alpha (air) \\rightarrow b(products)$$\n",
    "$$CH_4 + \\alpha O_2 + 3.76\\alpha N_2 \\rightarrow \\beta CO_2 + \\gamma H_2O + 3.76\\alpha N_2$$\n",
    "\n",
    "* Solve for $\\alpha$, $\\beta$, $\\gamma$, using elemental balnces on $C$, $H$, and $O$.\n",
    "    * C $\\rightarrow$ $1 = \\beta$ $\\rightarrow$ $\\beta = 1$\n",
    "    * H $\\rightarrow$ $4 = 2\\gamma$ $\\rightarrow$ $\\gamma = 2$\n",
    "    * O $\\rightarrow$ $2\\alpha = 2\\beta + \\gamma$ $\\rightarrow$ $\\alpha = 2$.\n",
    "    \n",
    "$$CH_4 + 2O_2 + 7.52N_2 \\rightarrow CO_2 + 2H_2O + 7.52N_2$$\n",
    "\n",
    "* Note, no change in moles for methane combustion.\n",
    "* Note the high $m_f/m_a = M_{CH4}/(9.52M_{air}) = 16/(9.52*29) = 0.058$\n",
    "* Note: A/F = 17.2.\n",
    "\n",
    "### Generalize the fuel\n",
    "\n",
    "$$C_xH_y + \\alpha O_2 + 3.76\\alpha N_2 \\rightarrow \\beta CO_2 + \\gamma H_2O + 3.76\\alpha N_2$$\n",
    "* (x and y are number of carbons and hydrogens here, not mole and mass fractions).\n",
    "* C, H balances $\\rightarrow$ $\\beta = x$, $\\gamma = y/2$.\n",
    "* O balance $\\rightarrow$ $2\\alpha = 2\\beta + \\gamma$ $\\rightarrow$ $\\alpha = x + y/4$\n",
    "\n",
    "$$C_xH_y + \\left(x+\\frac{y}{4}\\right)O_2 + 3.76\\left(x+\\frac{y}{4}\\right)N_2 \\rightarrow xCO_2 + \\frac{y}{2}H_2O + 3.76\\left(x+\\frac{y}{4}\\right)N_2$$\n",
    "\n",
    "* When is there no change in moles?\n",
    "    * Reactants: $1 + \\alpha + 3.76\\alpha$\n",
    "    * Products:  $x + y/2 + 3.76\\alpha$.\n",
    "    * $\\rightarrow$ (1+x + y/4 = x + y/2).\n",
    "    * $\\rightarrow$ $y=4$\n",
    "    * No change in moles for species with 4 hydrogens: methane, ethylene, etc.\n",
    " \n",
    "* **Ethylene is special**\n",
    "    * $y=$ so no change in moles.\n",
    "    * $M_{C2H4} = 28\\approx M_{air}$, so $\\rho_{air}\\approx\\rho_{fuel}$\n",
    "        * $\\rho = MP/RT$\n",
    " \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lean combustion\n",
    "\n",
    "* Too much air (the usual case).\n",
    "* Assume a **fixed** quantity of fuel, $F$.\n",
    "* Fraction excess air, use subscript $s$ for stoichiometric:\n",
    "$$E = \\frac{A - A_s}{A_s},$$\n",
    "* Divide the top and bottom by $F$:\n",
    "$$E = \\frac{A/F - A_s/F}{A_s/F} = \\frac{A/F}{A_s/F} - 1.$$\n",
    "\n",
    "* At stoichiometric conditions, $A_s$ is stoichiomtric amount of air for the given amount of fuel, and we have $A_s/F = (A/F)_s$ \n",
    "\n",
    "$$E = \\frac{A/F}{(A/F)_s} - 1 = \\frac{1}{\\Phi} - 1.$$\n",
    "\n",
    "Write the balanced reaction with excess air:\n",
    "\n",
    "$$C_xH_y + (1+E)\\left(x+\\frac{y}{4}\\right)(O_2 + 3.76 N_2) \\rightarrow xCO_2 + \\frac{y}{2}H_2O + E\\left(x+\\frac{y}{4}\\right)O_2 + (1+E)3.76\\left(x+\\frac{y}{4}\\right)N_2$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Rich combustion\n",
    "* Too much fuel.\n",
    "* This case is easy. \n",
    "    * If the stoichiometric air is taken as an air basis, then $\\Phi=F/F_s$.\n",
    "    * Or, $F = \\Phi F_s = \\Phi$ when we use $F_s=1$ as in our generic balance equation for $C_xH_y$.\n",
    "$$\\Phi C_xH_y + \\left(x+\\frac{y}{4}\\right)O_2 + 3.76\\left(x+\\frac{y}{4}\\right)N_2 \\rightarrow xCO_2 + \\frac{y}{2}H_2O + 3.76\\left(x+\\frac{y}{4}\\right)N_2 + (\\Phi-1)C_xH_y$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example\n",
    "* Natural gas boiler fired with 20% excess air.\n",
    "\n",
    "$$CH_4 + (1.2)\\cdot(2 O_2 + 7.52 N_2) \\rightarrow CO_2 + 2H_2O + (1.2)\\cdot 7.52 N_2 + (0.2)\\cdot 2 O_2$$\n",
    "\n",
    "* Typical boilers run with excess air to compensate for imperfect mixing of fuel and air to prevent emissions of fuel or partially burnt species, such as CO."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "species    X      Y   \n",
      "----------------------\n",
      "CO2      0.0805 0.1273\n",
      "H2O      0.1610 0.1042\n",
      "O2       0.0322 0.0370\n",
      "N2       0.7263 0.7314\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import cantera as ct\n",
    "\n",
    "gas = ct.Solution(\"gri30.yaml\")\n",
    "\n",
    "gas.X = \"CO2:1, H2O:2, N2:9.024, O2:0.4\"\n",
    "\n",
    "sp  = [\"CO2\", \"H2O\", \"O2\", \"N2\"]\n",
    "iSp = [gas.species_index(k) for k in sp]\n",
    "X   = gas.X[iSp]\n",
    "Y   = gas.Y[iSp]\n",
    "\n",
    "print(f\"{'species':8} {'X':^6} {'Y':^6}\")\n",
    "print(f\"{'-'*22:22}\")\n",
    "for i in range(len(sp)):\n",
    "    print(f'{sp[i]:8s} {X[i]:6.4f} {Y[i]:6.4f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* With 20% excess air, we get 3% O$_2$ (by mole) in the flue gas.\n",
    "\n",
    "Typical systems\n",
    "* Natural Gas: 10-20% Excess air\n",
    "* Oil: 10-20\n",
    "* Coal: 20-25\n",
    "* Stoker: 35-40\n",
    "\n",
    "* Often, the O$_2$ in the flue gas is given on a dry basis. See Turns Chapter 15."
   ]
  }
 ],
 "metadata": {
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.13.1"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
