{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Stoichiometric reactions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**The thermosteam.reaction package contains array based objects that can model stoichiometric reactions given a conversion.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Single reaction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a Reaction object based on the transesterification reaction:\n",
    "\n",
    "|Reaction|Reactant|% Converted|\n",
    "|---|---|---|\n",
    "|Lipid + 3Methanol -> 3Biodiesel + Glycerol|Lipid|90|\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Reaction (by mol):\n",
      " stoichiometry                                 reactant    X[%]\n",
      " 3 Methanol + Lipid -> Glycerol + 3 Biodiesel  Lipid      90.00\n"
     ]
    }
   ],
   "source": [
    "import thermosteam as tmo\n",
    "from thermosteam import reaction as rxn\n",
    "from biorefineries.lipidcane.chemicals import lipidcane_chemicals\n",
    "\n",
    "tmo.settings.set_thermo(lipidcane_chemicals)\n",
    "transesterification = rxn.Reaction('Lipid + 3Methanol -> 3Biodiesel + Glycerol',\n",
    "                                   reactant='Lipid',  X=0.9)\n",
    "transesterification"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "CompiledChemicals([Water, Methanol, Ethanol, Glycerol, Glucose, Sucrose, H3PO4, P4O10, CO2, Octane, O2, Biodiesel, Ash, Cellulose, Hemicellulose, Flocculant, Lignin, Solids, DryYeast, CaO, HCl, NaOH, NaOCH3, Lipid])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "transesterification.chemicals"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0., -3.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  3.,  0.,\n",
       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0., -1.])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "transesterification.stoichiometry"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Lipid'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "transesterification.reactant"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "transesterification.X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "51642.0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "transesterification.dH # Heat of reaction J / mol-reacted"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When a Reaction object is called with a stream, it updates the material data to reflect the reaction:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BEFORE REACTION\n",
      "Stream: s1\n",
      " phase: 'l', T: 298.15 K, P: 101325 Pa\n",
      " flow (kmol/hr): Methanol  600\n",
      "                 Lipid     100\n",
      "AFTER REACTION\n",
      "Stream: s1\n",
      " phase: 'l', T: 298.15 K, P: 101325 Pa\n",
      " flow (kmol/hr): Methanol   330\n",
      "                 Glycerol   90\n",
      "                 Biodiesel  270\n",
      "                 Lipid      10\n"
     ]
    }
   ],
   "source": [
    "feed = tmo.Stream(Lipid=100, Methanol=600)\n",
    "print('BEFORE REACTION')\n",
    "feed.show(N=100)\n",
    "\n",
    "# React feed molar flow rate\n",
    "transesterification(feed)\n",
    "\n",
    "print('AFTER REACTION')\n",
    "feed.show(N=100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's change the basis of the reaction:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Reaction (by wt):\n",
      " stoichiometry                                           reactant    X[%]\n",
      " 0.109 Methanol + Lipid -> 0.104 Glycerol + 1 Biodiesel  Lipid      90.00\n"
     ]
    }
   ],
   "source": [
    "transesterification.basis = 'wt'\n",
    "transesterification"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that the stoichiometry also adjusted. If we react a stream, we should see the same result, regardless of basis:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BEFORE REACTION\n",
      "Stream: s2\n",
      " phase: 'l', T: 298.15 K, P: 101325 Pa\n",
      " flow (kmol/hr): Methanol  600\n",
      "                 Lipid     100\n",
      "AFTER REACTION\n",
      "Stream: s2\n",
      " phase: 'l', T: 298.15 K, P: 101325 Pa\n",
      " flow (kmol/hr): Methanol   330\n",
      "                 Glycerol   90\n",
      "                 Biodiesel  270\n",
      "                 Lipid      10\n"
     ]
    }
   ],
   "source": [
    "feed = tmo.Stream(Lipid=100, Methanol=600)\n",
    "print('BEFORE REACTION')\n",
    "feed.show(N=100)\n",
    "\n",
    "# React feed molar flow rate\n",
    "transesterification(feed)\n",
    "\n",
    "print('AFTER REACTION')\n",
    "feed.show(N=100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The heat of reaction is now in units of J/kg-reactant:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "58.32406836499681"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "transesterification.dH # Accounts for conversion too"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The only situation which you need to watch out for is when you pass an array (where each entry corresponds to a chemical), in which case the reaction object will assume the array is in the same basis. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BEFORE REACTION\n",
      "Stream: s3\n",
      " phase: 'l', T: 298.15 K, P: 101325 Pa\n",
      " flow (kmol/hr): Methanol  600\n",
      "                 Lipid     100\n",
      "AFTER BAD REACTION\n",
      "Stream: s3\n",
      " phase: 'l', T: 298.15 K, P: 101325 Pa\n",
      " flow (kmol/hr): Methanol   590\n",
      "                 Glycerol   9.36\n",
      "                 Biodiesel  90.4\n",
      "                 Lipid      10\n"
     ]
    }
   ],
   "source": [
    "feed = tmo.Stream(Lipid=100, Methanol=600)\n",
    "print('BEFORE REACTION')\n",
    "feed.show(N=100)\n",
    "\n",
    "# React molar flow rate array on a mass basis.\n",
    "# If this doesn't sound right, its because its not;\n",
    "# as you can see in the result.\n",
    "mol_array = feed.mol\n",
    "transesterification(mol_array)\n",
    "\n",
    "print('AFTER BAD REACTION')\n",
    "feed.show(N=100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you're not sure your equation is correct, you could also correct the stoichiometry through an atomic balance:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Reaction (by mol):\n",
      " stoichiometry                 reactant    X[%]\n",
      " Glucose -> 2 Ethanol + 2 CO2  Glucose    90.00\n"
     ]
    }
   ],
   "source": [
    "fermentation = rxn.Reaction('Glucose + O2 -> Ethanol + CO2',\n",
    "                            reactant='Glucose',  X=0.9,\n",
    "                            correct_atomic_balance=True)\n",
    "fermentation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But you cannot solve the atomic balance if your equation is underdetermined:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "ename": "RuntimeError",
     "evalue": "to solve atomic balance, number of atoms (3 available) must be equal to the number of chemicals, not including the reactant (2 available)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mRuntimeError\u001b[0m                              Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-13-19b51ae89dd7>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m fermentation = rxn.Reaction('Glucose -> Ethanol + CO2',\n\u001b[0;32m      2\u001b[0m                             \u001b[0mreactant\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'Glucose'\u001b[0m\u001b[1;33m,\u001b[0m  \u001b[0mX\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m0.9\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m                             correct_atomic_balance=True) \n\u001b[0m",
      "\u001b[1;32m~\\OneDrive\\Code\\thermosteam\\thermosteam\\reaction\\_reaction.py\u001b[0m in \u001b[0;36m__init__\u001b[1;34m(self, reaction, reactant, X, chemicals, basis, check_material_balance, check_atomic_balance, correct_atomic_balance)\u001b[0m\n\u001b[0;32m    162\u001b[0m             \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_rescale\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    163\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mcorrect_atomic_balance\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 164\u001b[1;33m                 \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcorrect_atomic_balance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    165\u001b[0m             \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    166\u001b[0m                 \u001b[1;32mif\u001b[0m \u001b[0mcheck_atomic_balance\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\OneDrive\\Code\\thermosteam\\thermosteam\\reaction\\_reaction.py\u001b[0m in \u001b[0;36mcorrect_atomic_balance\u001b[1;34m(self, constants)\u001b[0m\n\u001b[0;32m    371\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mM_atoms\u001b[0m \u001b[1;33m!=\u001b[0m \u001b[0mN_chemicals\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    372\u001b[0m             raise RuntimeError(\n\u001b[1;32m--> 373\u001b[1;33m                  \u001b[1;34m'to solve atomic balance, number of atoms '\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    374\u001b[0m                 \u001b[1;34mf'({M_atoms} available) must be equal to the number of '\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    375\u001b[0m                  \u001b[1;34m'chemicals, not including the reactant '\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mRuntimeError\u001b[0m: to solve atomic balance, number of atoms (3 available) must be equal to the number of chemicals, not including the reactant (2 available)"
     ]
    }
   ],
   "source": [
    "fermentation = rxn.Reaction('Glucose -> Ethanol + CO2',\n",
    "                            reactant='Glucose',  X=0.9,\n",
    "                            correct_atomic_balance=True) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lastly, when working with positive ions, simply pass a dictionary of stoichiometric coefficients instead of the equation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Reaction (by mol):\n",
      " stoichiometry      reactant    X[%]\n",
      " NaCl -> Na+ + Cl-  NaCl      100.00\n"
     ]
    }
   ],
   "source": [
    "# First let's define a new set of chemicals\n",
    "chemicals = NaOH, SodiumIon, ChlorideIon = tmo.Chemicals(['NaCl', 'Na+', 'Cl-'])\n",
    "\n",
    "# We set the state to completely ignore other possible phases\n",
    "NaOH.at_state('s')\n",
    "SodiumIon.at_state('l')\n",
    "ChlorideIon.at_state('l')\n",
    "\n",
    "# Molar volume doesn't matter in this scenario, but its\n",
    "# required to compile the chemicals. We can assume \n",
    "# a very low volume since its in solution.\n",
    "SodiumIon.V.add_model(1e-6)\n",
    "ChlorideIon.V.add_model(1e-6)\n",
    "\n",
    "# We can pass a Chemicals object to not have to override \n",
    "# the lipidcane chemicals we set earlier.\n",
    "dissociation = rxn.Reaction({'NaCl':-1, 'Na+':1, 'Cl-': 1},\n",
    "                            reactant='NaCl',  X=1.,\n",
    "                            chemicals=chemicals)\n",
    "dissociation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Parallel reactions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Model the pretreatment hydrolysis reactions and assumed conversions from Humbird et. al. as shown in the follwing table [[1]](#References):\n",
    "\n",
    "|Reaction|Reactant|% Converted|\n",
    "|---|---|---|\n",
    "|(Glucan)n + n H2O→ n Glucose|Glucan|9.9|\n",
    "|(Glucan)n + n H2O → n Glucose Oligomer|Glucan|0.3|\n",
    "|(Glucan)n → n HMF + 2n H2O|Glucan|0.3|\n",
    "|Sucrose → HMF + Glucose + 2 H2O|Sucrose|100.0|\n",
    "|(Xylan)n + n H2O→ n Xylose|Xylan|90.0|\n",
    "|(Xylan)n + m H2O → m Xylose Oligomer|Xylan|2.4|\n",
    "|(Xylan)n → n Furfural + 2n H2O|Xylan|5.0|\n",
    "|Acetate → Acetic Acid|Acetate|100.0|\n",
    "|(Lignin)n → n Soluble Lignin|Lignin|5.0|\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a ParallelReaction from Reaction objects:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ParallelReaction (by mol):\n",
      "index  stoichiometry                       reactant    X[%]\n",
      "[0]    Water + Glucan -> Glucose           Glucan      9.90\n",
      "[1]    Water + Glucan -> GlucoseOligomer   Glucan      0.30\n",
      "[2]    Glucan -> 2 Water + HMF             Glucan      0.30\n",
      "[3]    Sucrose -> 2 Water + HMF + Glucose  Sucrose     0.30\n",
      "[4]    Water + Xylan -> Xylose             Xylan      90.00\n",
      "[5]    Water + Xylan -> XyloseOligomer     Xylan       0.24\n",
      "[6]    Xylan -> 2 Water + Furfural         Xylan       0.50\n",
      "[7]    Acetate -> AceticAcid               Acetate   100.00\n",
      "[8]    Lignin -> SolubleLignin             Lignin      0.50\n"
     ]
    }
   ],
   "source": [
    "from biorefineries.cornstover.chemicals import cornstover_chemicals\n",
    "\n",
    "# Set chemicals as defined in [1-4]\n",
    "tmo.settings.set_thermo(cornstover_chemicals)\n",
    "\n",
    "# Create reactions\n",
    "pretreatment_parallel_rxn = rxn.ParallelReaction([\n",
    "    #            Reaction definition                 Reactant    Conversion\n",
    "    rxn.Reaction('Glucan + H2O -> Glucose',          'Glucan',   0.0990),\n",
    "    rxn.Reaction('Glucan + H2O -> GlucoseOligomer',  'Glucan',   0.0030),\n",
    "    rxn.Reaction('Glucan -> HMF + 2 H2O',            'Glucan',   0.0030),\n",
    "    rxn.Reaction('Sucrose -> HMF + Glucose + 2H2O',  'Sucrose',  0.0030),\n",
    "    rxn.Reaction('Xylan + H2O -> Xylose',            'Xylan',    0.9000),\n",
    "    rxn.Reaction('Xylan + H2O -> XyloseOligomer',    'Xylan',    0.0024),\n",
    "    rxn.Reaction('Xylan -> Furfural + 2 H2O',        'Xylan',    0.0050),\n",
    "    rxn.Reaction('Acetate -> AceticAcid',            'Acetate',  1.0000),\n",
    "    rxn.Reaction('Lignin -> SolubleLignin',          'Lignin',   0.0050)])\n",
    "\n",
    "pretreatment_parallel_rxn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Model the reaction:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BEFORE REACTION\n",
      "Stream: s4\n",
      " phase: 'l', T: 298.15 K, P: 101325 Pa\n",
      " flow (kmol/hr): Water     2.07e+05\n",
      "                 Ethanol   18\n",
      "                 Furfural  172\n",
      "                 H2SO4     1.84e+03\n",
      "                 Sucrose   1.87\n",
      "                 Extract   67.8\n",
      "                 Acetate   25.1\n",
      "                 Ash       4.11e+03\n",
      "                 Lignin    1.31e+04\n",
      "                 Protein   108\n",
      "                 Glucan    180\n",
      "                 Xylan     123\n",
      "                 Arabinan  9.02\n",
      "                 Mannan    3.08\n",
      "AFTER REACTION\n",
      "Stream: s4\n",
      " phase: 'l', T: 298.15 K, P: 101325 Pa\n",
      " flow (kmol/hr): Water            2.07e+05\n",
      "                 Ethanol          18\n",
      "                 AceticAcid       25.1\n",
      "                 Furfural         173\n",
      "                 H2SO4            1.84e+03\n",
      "                 HMF              0.546\n",
      "                 Glucose          17.8\n",
      "                 Xylose           111\n",
      "                 Sucrose          1.86\n",
      "                 Extract          67.8\n",
      "                 Ash              4.11e+03\n",
      "                 Lignin           1.3e+04\n",
      "                 SolubleLignin    65.5\n",
      "                 GlucoseOligomer  0.54\n",
      "                 XyloseOligomer   0.295\n",
      "                 Protein          108\n",
      "                 Glucan           161\n",
      "                 Xylan            11.4\n",
      "                 Arabinan         9.02\n",
      "                 Mannan           3.08\n"
     ]
    }
   ],
   "source": [
    "feed = tmo.Stream(H2O=2.07e+05,\n",
    "                  Ethanol=18,\n",
    "                  H2SO4=1.84e+03,\n",
    "                  Sucrose=1.87,\n",
    "                  Extract=67.8,\n",
    "                  Acetate=25.1,\n",
    "                  Ash=4.11e+03,\n",
    "                  Lignin=1.31e+04,\n",
    "                  Protein=108,\n",
    "                  Glucan=180,\n",
    "                  Xylan=123,\n",
    "                  Arabinan=9.02,\n",
    "                  Mannan=3.08,\n",
    "                  Furfural=172)\n",
    "print('BEFORE REACTION')\n",
    "feed.show(N=100)\n",
    "\n",
    "# React feed molar flow rate\n",
    "pretreatment_parallel_rxn(feed)\n",
    "\n",
    "print('AFTER REACTION')\n",
    "feed.show(N=100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reactions in series"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "SeriesReaction objects work the same way, but in series:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SeriesReaction (by mol):\n",
      "index  stoichiometry                       reactant    X[%]\n",
      "[0]    Water + Glucan -> Glucose           Glucan      9.90\n",
      "[1]    Water + Glucan -> GlucoseOligomer   Glucan      0.30\n",
      "[2]    Glucan -> 2 Water + HMF             Glucan      0.30\n",
      "[3]    Sucrose -> 2 Water + HMF + Glucose  Sucrose     0.30\n",
      "[4]    Water + Xylan -> Xylose             Xylan      90.00\n",
      "[5]    Water + Xylan -> XyloseOligomer     Xylan       0.24\n",
      "[6]    Xylan -> 2 Water + Furfural         Xylan       0.50\n",
      "[7]    Acetate -> AceticAcid               Acetate   100.00\n",
      "[8]    Lignin -> SolubleLignin             Lignin      0.50\n"
     ]
    }
   ],
   "source": [
    "pretreatment_series_rxn = rxn.SeriesReaction(pretreatment_parallel_rxn)\n",
    "pretreatment_series_rxn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Net conversion in parallel:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ChemicalIndexer:\n",
      " Sucrose  0.003\n",
      " Acetate  1\n",
      " Lignin   0.005\n",
      " Glucan   0.105\n",
      " Xylan    0.9074\n"
     ]
    }
   ],
   "source": [
    "pretreatment_parallel_rxn.X_net"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Net conversion in series:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ChemicalIndexer:\n",
      " Sucrose  0.003\n",
      " Acetate  1\n",
      " Lignin   0.005\n",
      " Glucan   0.1044\n",
      " Xylan    0.9007\n"
     ]
    }
   ],
   "source": [
    "# Notice how the conversion is\n",
    "# slightly lower for some reactants\n",
    "pretreatment_series_rxn.X_net"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BEFORE REACTION\n",
      "Stream: s5\n",
      " phase: 'l', T: 298.15 K, P: 101325 Pa\n",
      " flow (kmol/hr): Water     2.07e+05\n",
      "                 Ethanol   18\n",
      "                 Furfural  172\n",
      "                 H2SO4     1.84e+03\n",
      "                 Sucrose   1.87\n",
      "                 Extract   67.8\n",
      "                 Acetate   25.1\n",
      "                 Ash       4.11e+03\n",
      "                 Lignin    1.31e+04\n",
      "                 Protein   108\n",
      "                 Glucan    180\n",
      "                 Xylan     123\n",
      "                 Arabinan  9.02\n",
      "                 Mannan    3.08\n",
      "AFTER REACTION\n",
      "Stream: s5\n",
      " phase: 'l', T: 298.15 K, P: 101325 Pa\n",
      " flow (kmol/hr): Water            2.07e+05\n",
      "                 Ethanol          18\n",
      "                 AceticAcid       25.1\n",
      "                 Furfural         172\n",
      "                 H2SO4            1.84e+03\n",
      "                 HMF              0.491\n",
      "                 Glucose          17.8\n",
      "                 Xylose           111\n",
      "                 Sucrose          1.86\n",
      "                 Extract          67.8\n",
      "                 Ash              4.11e+03\n",
      "                 Lignin           1.3e+04\n",
      "                 SolubleLignin    65.5\n",
      "                 GlucoseOligomer  0.487\n",
      "                 XyloseOligomer   0.0295\n",
      "                 Protein          108\n",
      "                 Glucan           161\n",
      "                 Xylan            12.2\n",
      "                 Arabinan         9.02\n",
      "                 Mannan           3.08\n"
     ]
    }
   ],
   "source": [
    "feed = tmo.Stream(H2O=2.07e+05,\n",
    "                  Ethanol=18,\n",
    "                  H2SO4=1.84e+03,\n",
    "                  Sucrose=1.87,\n",
    "                  Extract=67.8,\n",
    "                  Acetate=25.1,\n",
    "                  Ash=4.11e+03,\n",
    "                  Lignin=1.31e+04,\n",
    "                  Protein=108,\n",
    "                  Glucan=180,\n",
    "                  Xylan=123,\n",
    "                  Arabinan=9.02,\n",
    "                  Mannan=3.08,\n",
    "                  Furfural=172)\n",
    "print('BEFORE REACTION')\n",
    "feed.show(N=100)\n",
    "\n",
    "# React feed molar flow rate\n",
    "pretreatment_series_rxn(feed)\n",
    "\n",
    "print('AFTER REACTION')\n",
    "feed.show(N=100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Indexing reactions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Both SeriesReaction, and ParallelReaction objects are indexable:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ParallelReaction (by mol):\n",
      "index  stoichiometry                      reactant    X[%]\n",
      "[0]    Water + Glucan -> Glucose          Glucan      9.90\n",
      "[1]    Water + Glucan -> GlucoseOligomer  Glucan      0.30\n"
     ]
    }
   ],
   "source": [
    "# Index a slice\n",
    "pretreatment_parallel_rxn[0:2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ReactionItem (by mol):\n",
      " stoichiometry              reactant    X[%]\n",
      " Water + Glucan -> Glucose  Glucan      9.90\n"
     ]
    }
   ],
   "source": [
    "# Index an item\n",
    "pretreatment_parallel_rxn[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Change conversion through the item\n",
    "pretreatment_parallel_rxn[0].X = 0.10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ParallelReaction (by mol):\n",
      "index  stoichiometry                       reactant    X[%]\n",
      "[0]    Water + Glucan -> Glucose           Glucan     10.00\n",
      "[1]    Water + Glucan -> GlucoseOligomer   Glucan      0.30\n",
      "[2]    Glucan -> 2 Water + HMF             Glucan      0.30\n",
      "[3]    Sucrose -> 2 Water + HMF + Glucose  Sucrose     0.30\n",
      "[4]    Water + Xylan -> Xylose             Xylan      90.00\n",
      "[5]    Water + Xylan -> XyloseOligomer     Xylan       0.24\n",
      "[6]    Xylan -> 2 Water + Furfural         Xylan       0.50\n",
      "[7]    Acetate -> AceticAcid               Acetate   100.00\n",
      "[8]    Lignin -> SolubleLignin             Lignin      0.50\n"
     ]
    }
   ],
   "source": [
    "pretreatment_parallel_rxn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice how changing conversion of a ReationItem object changes the converion in the ParallelReaction object."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### References\n",
    "\n",
    "<a id='References'></a>\n",
    "\n",
    "1. Humbird, D., Davis, R., Tao, L., Kinchin, C., Hsu, D., Aden, A., Dudgeon, D. (2011). Process Design and Economics for Biochemical Conversion of Lignocellulosic Biomass to Ethanol: Dilute-Acid Pretreatment and Enzymatic Hydrolysis of Corn Stover (No. NREL/TP-5100-47764, 1013269). https://doi.org/10.2172/1013269\n",
    "\n",
    "2. Hatakeyama, T., Nakamura, K., & Hatakeyama, H. (1982). Studies on heat capacity of cellulose and lignin by differential scanning calorimetry. Polymer, 23(12), 1801–1804. https://doi.org/10.1016/0032-3861(82)90125-2\n",
    "\n",
    "3. Thybring, E. E. (2014). Explaining the heat capacity of wood constituents by molecular vibrations. Journal of Materials Science, 49(3), 1317–1327. https://doi.org/10.1007/s10853-013-7815-6\n",
    "\n",
    "4. Murphy W. K., and K. R. Masters. (1978). Gross heat of combustion of northern red oak (Quercus rubra) chemical components. Wood Sci. 10:139-141."
   ]
  }
 ],
 "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.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
