{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Defining chemical systems\n", "\n", "
Written by Allan Leal (ETH Zurich) on Jan 4th, 2022
\n", "\n", "```{attention}\n", "Always make sure you are using the [latest version of Reaktoro](https://anaconda.org/conda-forge/reaktoro). Otherwise, some new features documented on this website will not work on your machine and you may receive unintuitive errors. Follow these [update instructions](updating_reaktoro_via_conda) to get the latest version of Reaktoro!\n", "```\n", "\n", "Before performing chemical reaction calculations, such as chemical equilibrium and kinetics, we need to determine the phases that must be considered in the calculation and the chemical species that constitute these phases.\n", "\n", "For example, to calculate the solubility of a mineral in water, two phases must be considered:\n", "\n", "* an aqueous phase representing water and dissolved species; and\n", "* a solid phase representing the mineral we want to dissolve in the aqueous solution.\n", "\n", "Another example is the combustion of a solid substance. We must define a chemical system composed of:\n", "\n", "* a gaseous phase containing most of the gases relevant to the process; and\n", "* one or more solid/liquid substances (condensed phases) that may appear during the combustion process.\n", "\n", "The concept of a chemical system is represented in Reaktoro using the {{ChemicalSystem}} class. You should expect to construct one object of this class for almost every chemical process you want to model. \n", "\n", "In a {{ChemicalSystem}} object, you can find a list of {{Phase}} objects representing the phases. The {{Phase}} class is also an essential component of Reaktoro. It contains the list of chemical species composing the phase, as a list of {{Species}} objects. Additionally, each {{Phase}} object includes its activity model to account for its non-ideal thermodynamic behavior. \n", "\n", "```{note}\n", "We'll learn more about activity models in a subsequent section and how to specify them for our phases.\n", "```\n", "\n", "Next, we will present how to construct a chemical system in Reaktoro for different applications." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Chemical system definition for a mineral solubility problem\n", "\n", "Let's consider the chemical equilibrium problem associated with calculating the solubility of halite (NaCl) in water. The code block below demonstrates how a {{ChemicalSystem}} object is created with an aqueous and mineral phase." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from reaktoro import *\n", "\n", "# Let's use one of PHREEQC's database\n", "db = PhreeqcDatabase(\"phreeqc.dat\")\n", "\n", "# Define an aqueous solution with species that are pertinent to the problem\n", "solution = AqueousPhase(\"H2O H+ OH- Na+ Cl-\")\n", "\n", "# Because we want to compute the solubility of halite, a mineral phase is needed\n", "halite = MineralPhase(\"Halite\")\n", "\n", "# We can now create our ChemicalSystem object with the above phase specifications\n", "system = ChemicalSystem(db, solution, halite)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's it! With the {{ChemicalSystem}} object created above, we can do some exciting things. For example, we can inspect the phases in the system and their composing chemical species:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AqueousPhase\n", ":: H2O\n", ":: H+\n", ":: OH-\n", ":: Na+\n", ":: Cl-\n", "Halite\n", ":: Halite\n" ] } ], "source": [ "for phase in system.phases():\n", " print(phase.name())\n", " for species in phase.species():\n", " print(\":: \" + species.name())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{note}\n", "Reaktoro has default names for phases, such as `AqueousPhase` and `GaseousPhase` for aqueous and gaseous phases. For pure mineral phases, the phase name is the same as the name of the mineral species composing it. That's is why the mineral phase above is named `Halite`, whose only composing species is called `Halite`. Note also that Reaktoro supports as many phases as you wish, each phase containing any number of species. We will demonstrate this in subsequent tutorials.\n", "```\n", "\n", "We can also inspect how the chemical species are ordered in the system:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "H2O\n", "H+\n", "OH-\n", "Na+\n", "Cl-\n", "Halite\n" ] } ], "source": [ "for species in system.species():\n", " print(species.name())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And inspect the chemical elements in the system:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "H\n", "O\n", "Na\n", "Cl\n" ] } ], "source": [ "for element in system.elements():\n", " print(element.symbol())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The {{ChemicalSystem}} class also contains the formula matrix $A$ of the system, which is a matrix whose entry $A_{j,i}$ contains the number of atoms of element with index $j$ in species with index $i$:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 2. 1. 1. 0. 0. 0.]\n", " [ 1. 0. 1. 0. 0. 0.]\n", " [ 0. 0. 0. 1. 0. 1.]\n", " [ 0. 0. 0. 0. 1. 1.]\n", " [ 0. 1. -1. 1. -1. 0.]]\n" ] } ], "source": [ "print(system.formulaMatrix())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The last row in the formula matrix contains the electric charge of each species.\n", "\n", "```{tip}\n", "Access the link {{ChemicalSystem}} to find out all methods available in class `ChemicalSystem`!\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Chemical system definition for a gas solubility problem\n", "\n", "We now consider a chemical system of interest for the computation of CO2 solubility in saline solutions. For this case, we will need an aqueous and gaseous phase:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from reaktoro import *\n", "\n", "# Let's use the SUPCRTBL database this time (its complete version that includes organic species)\n", "db = SupcrtDatabase(\"supcrtbl-organics\")\n", "\n", "# Define an aqueous solution with automatic species collection for given selected elements\n", "solution = AqueousPhase(speciate(\"H O Na Cl Ca C\"))\n", "\n", "# Let Reaktoro automatically identify the gases by specifying an empty list of species below\n", "gas = GaseousPhase()\n", "\n", "# We can now create our ChemicalSystem object with the above phase specifications\n", "system = ChemicalSystem(db, solution, gas)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's print the species in the system, their names, formula, and molar mass:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "tags": [ "scroll-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Name Formula Molar Mass (kg/mol) \n", "H2O(aq) H2O 0.018015 \n", "CaOH+ CaOH+ 0.057085 \n", "CO(aq) CO 0.028010 \n", "CO2(aq) CO2 0.044010 \n", "CO3-2 CO3-2 0.060010 \n", "Ca(HCO3)+ Ca(HCO3)+ 0.101095 \n", "Ca+2 Ca+2 0.040077 \n", "CaCl+ CaCl+ 0.075530 \n", "CaCl2(aq) CaCl2 0.110983 \n", "Cl- Cl- 0.035453 \n", "HClO(aq) HClO 0.052460 \n", "ClO- ClO- 0.051453 \n", "ClO2- ClO2- 0.067452 \n", "ClO3- ClO3- 0.083451 \n", "ClO4- ClO4- 0.099451 \n", "H+ H+ 0.001007 \n", "H2(aq) H2 0.002016 \n", "HCO3- HCO3- 0.061018 \n", "HO2- HO2- 0.033007 \n", "Na+ Na+ 0.022989 \n", "NaCl(aq) NaCl 0.058442 \n", "NaOH(aq) NaOH 0.039997 \n", "O2(aq) O2 0.031999 \n", "OH- OH- 0.017008 \n", "H2O2(aq) H2O2 0.034015 \n", "HClO2(aq) HClO2 0.068459 \n", "HCl(aq) HCl 0.036461 \n", "CaCO3(aq) CaCO3 0.100087 \n", "CH4(aq) CH4 0.016043 \n", "H-Acetate(aq) C2H4O2 0.060053 \n", "Acetate- C2H3O2- 0.059045 \n", "1-Butanol(aq) C4H9OH 0.074123 \n", "1-Butene(aq) C4H8 0.056108 \n", "1-Butyne(aq) C4H6 0.054092 \n", "1-Heptanol(aq) C7H15OH 0.116203 \n", "1-Heptene(aq) C7H14 0.098188 \n", "1-Heptyne(aq) C7H12 0.096172 \n", "1-Hexanol(aq) C6H13OH 0.102177 \n", "1-Hexene(aq) C6H12 0.084161 \n", "1-Hexyne(aq) C6H10 0.082145 \n", "1-Octanol(aq) C8H17OH 0.130230 \n", "1-Octene(aq) C8H16 0.112215 \n", "1-Octyne(aq) C8H14 0.110199 \n", "1-Pentanol(aq) C5H11OH 0.088150 \n", "1-Pentene(aq) C5H10 0.070134 \n", "1-Pentyne(aq) C5H8 0.068119 \n", "1-Propanol(aq) C3H7OH 0.060096 \n", "1-Propene(aq) C3H6 0.042081 \n", "1-Propyne(aq) C3H4 0.040065 \n", "2-Butanone(aq) C4H8O 0.072107 \n", "2-Heptanone(aq) C7H14O 0.114188 \n", "2-Hexanone(aq) C6H12O 0.100161 \n", "2-Hydroxybutanoate C4H7O3- 0.103098 \n", "2-Hydroxybutanoic(aq) C4H8O3 0.104106 \n", "2-Hydroxydecanoate C10H19O3- 0.187260 \n", "2-Hydroxydecanoic(aq) C10H20O3 0.188267 \n", "2-Hydroxyheptanoic C7H14O3 0.146186 \n", "2-Hydroxyhexanoate C6H11O3- 0.131152 \n", "2-Hydroxyhexanoic(aq) C6H12O3 0.132159 \n", "2-Hydroxynonanoate C9H17O3- 0.173233 \n", "2-Hydroxynonanoic(aq) C9H18O3 0.174240 \n", "2-Hydroxyoctanoate C8H15O3- 0.159206 \n", "2-Hydroxyoctanoic(aq) C8H16O3 0.160213 \n", "2-Hydroxypentanoic C5H10O3 0.118133 \n", "2-Octanone(aq) C8H16O 0.128214 \n", "2-Pentanone(aq) C5H10O 0.086134 \n", "Acetone(aq) C3H6O 0.058080 \n", "Adipate C6H8O4-2 0.144128 \n", "Adipic-Acid(aq) C6H10O4 0.146143 \n", "Azelaic-Acid(aq) C9H16O4 0.188224 \n", "Azelate C9H14O4-2 0.186209 \n", "Benzene(aq) C6H6 0.078114 \n", "Benzoate C7H5O2- 0.121116 \n", "Benzoic-Acid(aq) C7H6O2 0.122123 \n", "o-Cresol(aq) C6H4OHCH3 0.108140 \n", "m-Cresol(aq) C6H4OHCH3 0.108140 \n", "p-Cresol(aq) C6H4OHCH3 0.108140 \n", "Decanoate C10H19O2- 0.171260 \n", "Decanoic-Acid(aq) C10H20O2 0.172268 \n", "2,3-DMP(aq) C6H3OHCH3CH3 0.122167 \n", "2,4-DMP(aq) C6H3OHCH3CH3 0.122167 \n", "2,5-DMP(aq) C6H3OHCH3CH3 0.122167 \n", "2,6-DMP(aq) C6H3OHCH3CH3 0.122167 \n", "3,4-DMP(aq) C6H3OHCH3CH3 0.122167 \n", "3,5-DMP(aq) C6H3OHCH3CH3 0.122167 \n", "Dodecanoate C12H23O2- 0.199314 \n", "Dodecanoic-Acid(aq) C12H24O2 0.200321 \n", "Ethane(aq) C2H6 0.030070 \n", "Ethanol(aq) C2H5OH 0.046069 \n", "Ethylacetate(aq) CH3COOCH2CH3 0.088106 \n", "Ethylbenzene(aq) C6H5C2H5 0.106167 \n", "Ethylene(aq) C2H4 0.028054 \n", "Ethyne(aq) C2H2 0.026038 \n", "Glutarate C5H6O4-2 0.130101 \n", "Glutaric-Acid(aq) C5H8O4 0.132116 \n", "H-Adipate C6H9O4- 0.145136 \n", "H-Azelate C9H15O4- 0.187216 \n", "H-Glutarate C5H7O4- 0.131109 \n", "H-Malonate C3H3O4- 0.103055 \n", "H-Oxalate C2HO4- 0.089028 \n", "H-Pimelate C7H11O4- 0.159162 \n", "H-Sebacate C10H17O4- 0.201243 \n", "H-Suberate C8H13O4- 0.173189 \n", "H-Succinate C4H5O4- 0.117082 \n", "Heptanoate C7H13O2- 0.129180 \n", "Heptanoic-Acid(aq) C7H14O2 0.130187 \n", "Hexanoate C6H11O2- 0.115153 \n", "Hexanoic-Acid(aq) C6H12O2 0.116160 \n", "m-Toluate C8H7O2- 0.135143 \n", "m-Toluic-Acid(aq) C8H8O2 0.136150 \n", "Malonate C3H2O4-2 0.102048 \n", "Malonic-Acid(aq) C3H4O4 0.104062 \n", "Methanol(aq) CH3OH 0.032042 \n", "n-Butane(aq) C4H10 0.058123 \n", "n-Butylbenzene(aq) C6H5C4H9 0.134221 \n", "n-Heptane(aq) C7H16 0.100204 \n", "n-Heptylbenzene(aq) C6H5C7H15 0.176302 \n", "n-Hexane(aq) C6H14 0.086177 \n", "n-Hexylbenzene(aq) C6H5C6H13 0.162275 \n", "n-Octane(aq) C8H18 0.114231 \n", "n-Octylbenzene(aq) C6H5C8H17 0.190329 \n", "n-Pentane(aq) C5H12 0.072150 \n", "n-Pentylbenzene(aq) C6H5C5H1 0.148248 \n", "n-Propylbenzene(aq) C6H5C3H7 0.120194 \n", "Nonanoate C9H17O2- 0.157233 \n", "Nonanoic-Acid(aq) C9H18O2 0.158241 \n", "o-Toluate C8H7O2- 0.135143 \n", "o-Toluic-Acid(aq) C8H8O2 0.136150 \n", "Octanoate C8H15O2- 0.143206 \n", "Octanoic-Acid(aq) C8H16O2 0.144214 \n", "Oxalate C2O4-2 0.088021 \n", "Oxalic-Acid(aq) C2H2O4 0.090035 \n", "p-Toluate C8H7O2- 0.135143 \n", "p-Toluic-Acid(aq) C8H8O2 0.136150 \n", "Phenol(aq) C6H5OH 0.094113 \n", "Pimelate C7H10O4-2 0.158155 \n", "Pimelic-Acid(aq) C7H12O4 0.160170 \n", "Propane(aq) C3H8 0.044097 \n", "Sebacate C10H16O4-2 0.200236 \n", "Sebacic-Acid(aq) C10H18O4 0.202251 \n", "Suberate C8H12O4-2 0.172182 \n", "Suberic-Acid(aq) C8H14O4 0.174197 \n", "Succinate C4H4O4-2 0.116074 \n", "Succinic-Acid(aq) C4H6O4 0.118089 \n", "Toluene(aq) C6H5CH3 0.092141 \n", "Undecanoate C11H21O2- 0.185287 \n", "Undecanoic-Acid(aq) C11H22O2 0.186294 \n", "Acetaldehyde(aq) CH3CHO 0.044053 \n", "Butanal(aq) CH3(CH2)2CHO 0.072107 \n", "Decanal(aq) CH3(CH2)8CHO 0.156268 \n", "Formaldehyde(aq) HCHO 0.030026 \n", "Heptanal(aq) CH3(CH2)5CHO 0.114188 \n", "Hexanal(aq) CH3(CH2)4CHO 0.100161 \n", "Nonanal(aq) CH3(CH2)7CHO 0.142241 \n", "Octanal(aq) CH3(CH2)6CHO 0.128214 \n", "Pentanal(aq) CH3(CH2)3CHO 0.086134 \n", "Propanal(aq) CH3CH2CHO 0.058080 \n", "Na(Ac)(aq) NaCH3COO 0.082034 \n", "Na(Ac)2- Na(CH3COO)2- 0.141080 \n", "Ca(Ac)+ CaCH3COO+ 0.099122 \n", "Ca(Ac)2(aq) Ca(CH3COO)2 0.158167 \n", "Lactate C3H5O3- 0.089071 \n", "Lactic-Acid(aq) C3H6O3 0.090079 \n", "Ca(Lac)+ CaCH3CH2OCO2+ 0.129148 \n", "Ca(Lac)2(aq) Ca(CH3CH2OCO2)2 0.218220 \n", "Na(Lac)(aq) NaCH3CH2OCO2 0.112061 \n", "Na(Lac)2- Na(CH3CH2OCO2)2- 0.201132 \n", "Glycolic-Acid(aq) C2H4O3 0.076052 \n", "Glycolate C2H3O3- 0.075045 \n", "Ca(Glyc)+ CaCH3OCO2+ 0.115121 \n", "Ca(Glyc)2(aq) Ca(CH3OCO2)2 0.190166 \n", "Na(Glyc)(aq) Na(CH3OCO2) 0.098034 \n", "Na(Glyc)2- Na(CH3OCO2)2- 0.173078 \n", "Formic-Acid(aq) H2CO2 0.046026 \n", "Formate HCO2- 0.045018 \n", "Ca(For)+ CaCHO2+ 0.085095 \n", "Ca(For)2(aq) Ca(CHO2)2 0.130113 \n", "Na(For)(aq) NaCHO2 0.068008 \n", "Na(For)2- Na(CHO2)2- 0.113026 \n", "Propanoic-Acid(aq) C3H6O2 0.074079 \n", "Propanoate C3H5O2- 0.073072 \n", "Ca(Prop)+ CaCH3CH2CO2+ 0.113149 \n", "Ca(Prop)2(aq) Ca(CH3CH2CO2)2 0.186221 \n", "Na(Prop)(aq) NaCH3CH2CO2 0.096061 \n", "Na(Prop)2- Na(CH3CH2CO2)2- 0.169133 \n", "Butanoic-Acid(aq) C4H8O2 0.088106 \n", "Butanoate C4H7O2- 0.087099 \n", "Ca(But)+ CaCH3(CH2)2CO2+ 0.127176 \n", "Ca(But)2(aq) Ca(CH3CH2CH2CO2)2 0.214275 \n", "Na(But)(aq) NaCH3(CH2)2CO2 0.110088 \n", "Na(But)2- Na(CH3CH2CH2CO2)2- 0.197187 \n", "Pentanoic-Acid(aq) C5H10O2 0.102133 \n", "Pentanoate C5H9O2- 0.101126 \n", "Ca(Pent)+ CaCH3(CH2)3CO2+ 0.141203 \n", "Ca(Pent)2(aq) Ca(CH3CH2CH2CH2CO2)2 0.242329 \n", "Na(Pent)(aq) NaCH3(CH2)3CO2 0.124115 \n", "Na(Pent)2- Na(CH3CH2CH2CH2CO2)2- 0.225241 \n", "CH4(g) CH4 0.016043 \n", "CO(g) CO 0.028010 \n", "CO2(g) CO2 0.044010 \n", "H2(g) H2 0.002016 \n", "O2(g) O2 0.031999 \n", "H2O(g) H2O 0.018015 \n", "Phenol(g) C6H5OH 0.094113 \n", "o-Cresol(g) CH3C6H4(OH) 0.108140 \n", "m-Cresol(g) CH3C6H4(OH) 0.108140 \n", "p-Cresol(g) CH3C6H4(OH) 0.108140 \n", "Ethylene(g) C2H4 0.028054 \n" ] } ], "source": [ "print(\"{:<25}{:<25}{:<20}\".format(\"Name\", \"Formula\", \"Molar Mass (kg/mol)\"))\n", "for species in system.species():\n", " print(\"{:<25}{:<25}{:<20.6f}\".format(species.name(), species.formula().str(), species.molarMass()))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This chemical system contains many species. The SUPCRTBL database contains many\n", "organic species that should play an insignificant role in accurately computing\n", "CO{{_2}} solubility. All organic species in SUPCRT and SUPCRTBL databases in\n", "Reaktoro’s YAML format have an organic tag which we can use to filter out them.\n", "\n", "Let's then redefine our {{ChemicalSystem}} object `system` by excluding those\n", "organic aqueous species and specifying exactly the gases we want:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "solution = AqueousPhase(speciate(\"H O Na Cl Ca C\"), exclude(\"organic\"))\n", "\n", "gas = GaseousPhase(\"CO2(g)\")\n", "\n", "system = ChemicalSystem(db, solution, gas)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{warning}\n", "Make sure you specify species names exactly how they exist in the {{Database}}\n", "object you have created, such as in `GaseousPhase(\"CO2(g)\")` above. Otherwise\n", "you will get a runtime exception!\n", "```\n", "\n", "```{note}\n", "You can use `SupcrtDatabase(\"supcrtbl\")` if you want the SUPCRTBL database version without organic species. In this case, the `exclude(\"organic\")` filter is not needed and has no effect. \n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And here is the updated list of species (only their names this time):" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "H2O(aq)\n", "CaOH+\n", "CO(aq)\n", "CO2(aq)\n", "CO3-2\n", "Ca(HCO3)+\n", "Ca+2\n", "CaCl+\n", "CaCl2(aq)\n", "Cl-\n", "HClO(aq)\n", "ClO-\n", "ClO2-\n", "ClO3-\n", "ClO4-\n", "H+\n", "H2(aq)\n", "HCO3-\n", "HO2-\n", "Na+\n", "NaCl(aq)\n", "NaOH(aq)\n", "O2(aq)\n", "OH-\n", "H2O2(aq)\n", "HClO2(aq)\n", "HCl(aq)\n", "CaCO3(aq)\n", "CO2(g)\n" ] } ], "source": [ "for species in system.species():\n", " print(species.name())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You may still be discontent with so many aqueous species for the sake of CO2 solubility calculation. We demonstrate with the code block below how to specify the exact aqueous species to be considered in the phase using a list of species names." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "aqueous_species = [\n", " \"H2O(aq)\", \n", " \"CaOH+\", \n", " \"CO2(aq)\", \n", " \"CO3-2\", \n", " \"Ca(HCO3)+\", \n", " \"Ca+2\", \n", " \"CaCl+\", \n", " \"Cl-\", \n", " \"H+\", \n", " \"HCO3-\", \n", " \"HO2-\", \n", " \"Na+\", \n", " \"OH-\"\n", "]\n", "\n", "solution = AqueousPhase(aqueous_species)\n", "\n", "system = ChemicalSystem(db, solution, gas)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "H2O(aq)\n", "CaOH+\n", "CO2(aq)\n", "CO3-2\n", "Ca(HCO3)+\n", "Ca+2\n", "CaCl+\n", "Cl-\n", "H+\n", "HCO3-\n", "HO2-\n", "Na+\n", "OH-\n", "CO2(g)\n" ] } ], "source": [ "for species in system.species():\n", " print(species.name())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Chemical system definition with many phases\n", "\n", "Now, let's overcomplicate and define a chemical system with many phases and\n", "species. We have an aqueous solution for which we know the chemical elements of\n", "interest. We want Reaktoro to automatically include in our chemical system all\n", "minerals that could potentially be important (e.g., minerals that could\n", "precipitate as the solution temperature is changed). These are minerals in the\n", "database whose constituting elements are found in the aqueous solution. We also\n", "want to show how a mineral phase can be defined as a solid solution (containing\n", "more than one mineral end-member).\n", "\n", "We demonstrate the above requirements for creating a chemical system in the\n", "code block below. Note the use of the `cemdata18` database provided by\n", "ThermoFun, which is suitable for modeling cement chemistry." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "db = ThermoFunDatabase(\"cemdata18\")\n", "\n", "solution = AqueousPhase(speciate(\"H O Na Cl Ca Mg C Si Fe Al K S\"))\n", "gas = GaseousPhase()\n", "pureminerals = MineralPhases()\n", "solidsolution = MineralPhase(\"ettringite Fe-ettringite\")\n", "\n", "system = ChemicalSystem(db, solution, gas, pureminerals, solidsolution)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's now print the phase names and their composing species:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "tags": [ "scroll-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AqueousPhase\n", ":: Al(SO4)+\n", ":: Al(SO4)2-\n", ":: Al+3\n", ":: AlO+\n", ":: AlO2-\n", ":: AlO2H@\n", ":: AlOH+2\n", ":: AlSiO5-3\n", ":: CH4@\n", ":: CO2@\n", ":: CO3-2\n", ":: Ca(CO3)@\n", ":: Ca(HCO3)+\n", ":: Ca(HSiO3)+\n", ":: Ca(SO4)@\n", ":: Ca+2\n", ":: CaOH+\n", ":: CaSiO3@\n", ":: Cl-\n", ":: ClO4-\n", ":: Fe(CO3)@\n", ":: Fe(HCO3)+\n", ":: Fe(HSO4)+\n", ":: Fe(HSO4)+2\n", ":: Fe(SO4)+\n", ":: Fe(SO4)2-\n", ":: Fe(SO4)@\n", ":: Fe+2\n", ":: Fe+3\n", ":: FeCl+\n", ":: FeCl+2\n", ":: FeCl2+\n", ":: FeCl3@\n", ":: FeO+\n", ":: FeO2-\n", ":: FeO2H@\n", ":: FeOH+\n", ":: FeOH+2\n", ":: H+\n", ":: H2@\n", ":: H2O@\n", ":: H2S@\n", ":: HCO3-\n", ":: HS-\n", ":: HSO3-\n", ":: HSO4-\n", ":: HSiO3-\n", ":: K(SO4)-\n", ":: K+\n", ":: KOH@\n", ":: Mg(CO3)@\n", ":: Mg(HCO3)+\n", ":: Mg(HSiO3)+\n", ":: Mg+2\n", ":: MgOH+\n", ":: MgSO4@\n", ":: Na(CO3)-\n", ":: Na(HCO3)@\n", ":: Na(SO4)-\n", ":: Na+\n", ":: NaOH@\n", ":: O2@\n", ":: OH-\n", ":: S2O3-2\n", ":: SO2@\n", ":: SO3-2\n", ":: SO4-2\n", ":: Si4O10-4\n", ":: SiO2@\n", ":: SiO3-2\n", "GaseousPhase\n", ":: CH4\n", ":: CO2\n", ":: H2\n", ":: H2O\n", ":: H2S\n", ":: O2\n", "ettringite\n", ":: ettringite\n", ":: Fe-ettringite\n", "5CA\n", ":: 5CA\n", "5CNA\n", ":: 5CNA\n", "AlOHam\n", ":: AlOHam\n", "AlOHmic\n", ":: AlOHmic\n", "Amor-Sl\n", ":: Amor-Sl\n", "Anh\n", ":: Anh\n", "Arg\n", ":: Arg\n", "Brc\n", ":: Brc\n", "C12A7\n", ":: C12A7\n", "C2AClH5\n", ":: C2AClH5\n", "C2AH65\n", ":: C2AH65\n", "C2AH7.5\n", ":: C2AH7.5\n", "C2S\n", ":: C2S\n", "C3A\n", ":: C3A\n", "C3AFS0.84H4.32\n", ":: C3AFS0.84H4.32\n", "C3AH6\n", ":: C3AH6\n", "C3AS0.41H5.18\n", ":: C3AS0.41H5.18\n", "C3AS0.84H4.32\n", ":: C3AS0.84H4.32\n", "C3FH6\n", ":: C3FH6\n", "C3FS0.84H4.32\n", ":: C3FS0.84H4.32\n", "C3FS1.34H3.32\n", ":: C3FS1.34H3.32\n", "C3S\n", ":: C3S\n", "C4AClH10\n", ":: C4AClH10\n", "C4AF\n", ":: C4AF\n", "C4AH11\n", ":: C4AH11\n", "C4AH13\n", ":: C4AH13\n", "C4AH19\n", ":: C4AH19\n", "C4AsClH12\n", ":: C4AsClH12\n", "C4FH13\n", ":: C4FH13\n", "CA\n", ":: CA\n", "CA2\n", ":: CA2\n", "CAH10\n", ":: CAH10\n", "CSH3T-T2C\n", ":: CSH3T-T2C\n", "CSH3T-T5C\n", ":: CSH3T-T5C\n", "CSH3T-TobH\n", ":: CSH3T-TobH\n", "CSHQ-JenD\n", ":: CSHQ-JenD\n", "CSHQ-JenH\n", ":: CSHQ-JenH\n", "CSHQ-TobD\n", ":: CSHQ-TobD\n", "CSHQ-TobH\n", ":: CSHQ-TobH\n", "Cal\n", ":: Cal\n", "Corundum\n", ":: Corundum\n", "Dis-Dol\n", ":: Dis-Dol\n", "ECSH1-KSH\n", ":: ECSH1-KSH\n", "ECSH1-NaSH\n", ":: ECSH1-NaSH\n", "ECSH1-SH\n", ":: ECSH1-SH\n", "ECSH1-TobCa\n", ":: ECSH1-TobCa\n", "ECSH2-JenCa\n", ":: ECSH2-JenCa\n", "ECSH2-KSH\n", ":: ECSH2-KSH\n", "ECSH2-NaSH\n", ":: ECSH2-NaSH\n", "ECSH2-TobCa\n", ":: ECSH2-TobCa\n", "Ettringite13_des\n", ":: Ettringite13_des\n", "Ettringite9_des\n", ":: Ettringite9_des\n", "Fe\n", ":: Fe\n", "Fe-ettringite\n", ":: Fe-ettringite\n", "Fe-ettringite05\n", ":: Fe-ettringite05\n", "Fe-hemicarbonate\n", ":: Fe-hemicarbonate\n", "Fe-monosulph05\n", ":: Fe-monosulph05\n", "Fe-monosulphate\n", ":: Fe-monosulphate\n", "Fe2O3\n", ":: Fe2O3\n", "FeOOHmic\n", ":: FeOOHmic\n", "Femonocarbonate\n", ":: Femonocarbonate\n", "Gbs\n", ":: Gbs\n", "Gp\n", ":: Gp\n", "Gr\n", ":: Gr\n", "Gt\n", ":: Gt\n", "Hem\n", ":: Hem\n", "INFCA\n", ":: INFCA\n", "INFCN\n", ":: INFCN\n", "INFCNA\n", ":: INFCNA\n", "Jennite\n", ":: Jennite\n", "K2O\n", ":: K2O\n", "K2SO4\n", ":: K2SO4\n", "KSiOH\n", ":: KSiOH\n", "Kln\n", ":: Kln\n", "Lim\n", ":: Lim\n", "M075SH\n", ":: M075SH\n", "M15SH\n", ":: M15SH\n", "M4A-OH-LDH\n", ":: M4A-OH-LDH\n", "M6A-OH-LDH\n", ":: M6A-OH-LDH\n", "M8A-OH-LDH\n", ":: M8A-OH-LDH\n", "Mag\n", ":: Mag\n", "Melanterite\n", ":: Melanterite\n", "Mg2AlC0.5OH\n", ":: Mg2AlC0.5OH\n", "Mg2FeC0.5OH\n", ":: Mg2FeC0.5OH\n", "Mg3AlC0.5OH\n", ":: Mg3AlC0.5OH\n", "Mg3FeC0.5OH\n", ":: Mg3FeC0.5OH\n", "Mgs\n", ":: Mgs\n", "Na2O\n", ":: Na2O\n", "Na2SO4\n", ":: Na2SO4\n", "NaSiOH\n", ":: NaSiOH\n", "Ord-Dol\n", ":: Ord-Dol\n", "Periclase\n", ":: Periclase\n", "Portlandite\n", ":: Portlandite\n", "Py\n", ":: Py\n", "Qtz\n", ":: Qtz\n", "Sd\n", ":: Sd\n", "Sulfur\n", ":: Sulfur\n", "T2C-CNASHss\n", ":: T2C-CNASHss\n", "T5C-CNASHss\n", ":: T5C-CNASHss\n", "Tob-I\n", ":: Tob-I\n", "Tob-II\n", ":: Tob-II\n", "TobH-CNASHss\n", ":: TobH-CNASHss\n", "Tro\n", ":: Tro\n", "chabazite\n", ":: chabazite\n", "ettringite!\n", ":: ettringite\n", "ettringite03_ss\n", ":: ettringite03_ss\n", "ettringite05\n", ":: ettringite05\n", "ettringite13\n", ":: ettringite13\n", "ettringite30\n", ":: ettringite30\n", "ettringite9\n", ":: ettringite9\n", "ettringite_ss\n", ":: ettringite_ss\n", "hemicarbonat10.5\n", ":: hemicarbonat10.5\n", "hemicarbonate\n", ":: hemicarbonate\n", "hemicarbonate9\n", ":: hemicarbonate9\n", "hemihydrate\n", ":: hemihydrate\n", "hydrotalcite\n", ":: hydrotalcite\n", "monocarbonate\n", ":: monocarbonate\n", "monocarbonate05\n", ":: monocarbonate05\n", "monocarbonate9\n", ":: monocarbonate9\n", "monosulphate10.5\n", ":: monosulphate10.5\n", "monosulphate12\n", ":: monosulphate12\n", "monosulphate1205\n", ":: monosulphate1205\n", "monosulphate14\n", ":: monosulphate14\n", "monosulphate16\n", ":: monosulphate16\n", "monosulphate9\n", ":: monosulphate9\n", "natrolite\n", ":: natrolite\n", "straetlingite\n", ":: straetlingite\n", "straetlingite5.5\n", ":: straetlingite5.5\n", "straetlingite7\n", ":: straetlingite7\n", "syngenite\n", ":: syngenite\n", "thaumasite\n", ":: thaumasite\n", "tricarboalu\n", ":: tricarboalu\n", "tricarboalu03\n", ":: tricarboalu03\n", "zeoliteP_Ca\n", ":: zeoliteP_Ca\n", "zeoliteX\n", ":: zeoliteX\n", "zeoliteY\n", ":: zeoliteY\n" ] } ], "source": [ "for phase in system.phases():\n", " print(phase.name())\n", " for species in phase.species():\n", " print(\":: \" + species.name())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{tip}\n", "If efficient calculations are required in your application, you may want to be more selective in the phases and species that populate your chemical system! Unfortunately, it is not always possible to know in advance the species that do not make sense for our model. So do it carefully. Ensure that for all thermodynamic/chemical conditions of interest (e.g. for temperature, pressure ranges of interest) the species you want to exclude from the system are negligible (i.e. exist with numerically zero or tiny amounts).\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Imagine, however, you are dealing with two minerals and water and you don't\n", "want to specify the chemical elements in the definition of the aqueous phase.\n", "This is what you can do:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "db = PhreeqcDatabase(\"phreeqc.dat\")\n", "\n", "solution = AqueousPhase()\n", "albite = MineralPhase(\"Albite\")\n", "kaolinite = MineralPhase(\"Kaolinite\")\n", "\n", "system = ChemicalSystem(db, albite, kaolinite, solution)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's now find out which aqueous species were selected automatically for our\n", "aqueous phase:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "H+\n", "H2O\n", "Al+3\n", "Al(OH)2+\n", "Al(OH)3\n", "Al(OH)4-\n", "AlOH+2\n", "H2\n", "H4SiO4\n", "H2SiO4-2\n", "H3SiO4-\n", "Na+\n", "OH-\n", "NaOH\n", "O2\n" ] } ], "source": [ "aqueousphase = system.phases().get(\"AqueousPhase\")\n", "for species in aqueousphase.species():\n", " print(species.name())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Chemical system definition for a combustion problem\n", "\n", "Forget about water now and let's construct a chemical system suitable for modeling the combustion of black powder. Black powder is composed of potassium nitrate (KNO3), charcoal (C10Ca0.026H4.774N0.039O1.234), and sulfur (S8).\n", "\n", "In the code block below we construct a chemical system using the chemical elements above. \n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "# Let's use the NASA-CEA database for this example\n", "db = NasaDatabase(\"nasa-cea\")\n", "\n", "# Consider all possible condensed phases (solid or liquid substances) with given elements\n", "condensed = CondensedPhases(speciate(\"K N O C Ca H S\"))\n", "\n", "# Automatically select the gases based on the elements above\n", "gases = GaseousPhase() \n", "\n", "# Create a chemical system suitable for modeling combustion of black powder!\n", "system = ChemicalSystem(db, gases, condensed)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We print below the gases and condensed phases constituting our chemical system:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "tags": [ "scroll-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Gases\n", ":: e-\n", ":: C\n", ":: C+\n", ":: C-\n", ":: CH\n", ":: CH+\n", ":: CH2\n", ":: CH3\n", ":: CH2OH\n", ":: CH2OH+\n", ":: CH3O\n", ":: CH4\n", ":: CH3OH\n", ":: CH3OOH\n", ":: CN\n", ":: CN+\n", ":: CN-\n", ":: CNN\n", ":: CO\n", ":: CO+\n", ":: COS\n", ":: CO2\n", ":: CO2+\n", ":: COOH\n", ":: CS\n", ":: CS2\n", ":: C2\n", ":: C2+\n", ":: C2-\n", ":: C2H\n", ":: C2H2,acetylene\n", ":: C2H2,vinylidene\n", ":: CH2CO,ketene\n", ":: O(CH)2O\n", ":: HO(CO)2OH\n", ":: C2H3,vinyl\n", ":: CH3CN\n", ":: CH3CO,acetyl\n", ":: C2H4\n", ":: C2H4O,ethylen-o\n", ":: CH3CHO,ethanal\n", ":: CH3COOH\n", ":: OHCH2COOH\n", ":: C2H5\n", ":: C2H6\n", ":: CH3N2CH3\n", ":: C2H5OH\n", ":: CH3OCH3\n", ":: CH3O2CH3\n", ":: CCN\n", ":: CNC\n", ":: OCCN\n", ":: C2N2\n", ":: C2O\n", ":: C2S2\n", ":: C3\n", ":: C3H3,1-propynl\n", ":: C3H3,2-propynl\n", ":: C3H4,allene\n", ":: C3H4,propyne\n", ":: C3H4,cyclo-\n", ":: C3H5,allyl\n", ":: C3H6,propylene\n", ":: C3H6,cyclo-\n", ":: C3H6O,propylox\n", ":: C3H6O,acetone\n", ":: C3H6O,propanal\n", ":: C3H7,n-propyl\n", ":: C3H7,i-propyl\n", ":: C3H8\n", ":: C3H8O,1propanol\n", ":: C3H8O,2propanol\n", ":: CNCOCN\n", ":: C3OS\n", ":: C3O2\n", ":: C3S2\n", ":: C4\n", ":: C4H2,butadiyne\n", ":: C4H4,1,3-cyclo-\n", ":: C4H6,butadiene\n", ":: C4H6,1butyne\n", ":: C4H6,2butyne\n", ":: C4H6,cyclo-\n", ":: C4H8,1-butene\n", ":: C4H8,cis2-buten\n", ":: C4H8,tr2-butene\n", ":: C4H8,isobutene\n", ":: C4H8,cyclo-\n", ":: (CH3COOH)2\n", ":: C4H9,n-butyl\n", ":: C4H9,i-butyl\n", ":: C4H9,s-butyl\n", ":: C4H9,t-butyl\n", ":: C4H10,n-butane\n", ":: C4H10,isobutane\n", ":: C4N2\n", ":: C5\n", ":: C5H6,1,3cyclo-\n", ":: C5H8,cyclo-\n", ":: C5H10,1-pentene\n", ":: C5H10,cyclo-\n", ":: C5H11,pentyl\n", ":: C5H11,t-pentyl\n", ":: C5H12,n-pentane\n", ":: C5H12,i-pentane\n", ":: CH3C(CH3)2CH3\n", ":: C6H2\n", ":: C6H5,phenyl\n", ":: C6H5O,phenoxy\n", ":: C6H6\n", ":: C6H5OH,phenol\n", ":: C6H10,cyclo-\n", ":: C6H12,1-hexene\n", ":: C6H12,cyclo-\n", ":: C6H13,n-hexyl\n", ":: C6H14,n-hexane\n", ":: C7H7,benzyl\n", ":: C7H8\n", ":: C7H8O,cresol-mx\n", ":: C7H14,1-heptene\n", ":: C7H15,n-heptyl\n", ":: C7H16,n-heptane\n", ":: C7H16,2-methylh\n", ":: C8H8,styrene\n", ":: C8H10,ethylbenz\n", ":: C8H16,1-octene\n", ":: C8H17,n-octyl\n", ":: C8H18,n-octane\n", ":: C8H18,isooctane\n", ":: C9H19,n-nonyl\n", ":: C10H8,naphthale\n", ":: C10H21,n-decyl\n", ":: C12H9,o-bipheny\n", ":: C12H10,biphenyl\n", ":: Ca\n", ":: Ca+\n", ":: CaH\n", ":: CaO\n", ":: CaO+\n", ":: CaOH\n", ":: CaOH+\n", ":: Ca(OH)2\n", ":: CaS\n", ":: Ca2\n", ":: H\n", ":: H+\n", ":: H-\n", ":: HCN\n", ":: HCO\n", ":: HCO+\n", ":: HCCN\n", ":: HCCO\n", ":: HNC\n", ":: HNCO\n", ":: HNO\n", ":: HNO2\n", ":: HNO3\n", ":: HO2\n", ":: HO2-\n", ":: H2\n", ":: H2+\n", ":: H2-\n", ":: HCHO,formaldehy\n", ":: HCOOH\n", ":: H2O\n", ":: H2O+\n", ":: H2O2\n", ":: H2S\n", ":: H2SO4\n", ":: H3O+\n", ":: (HCOOH)2\n", ":: K\n", ":: K+\n", ":: K-\n", ":: KCN\n", ":: KH\n", ":: KNO2\n", ":: KNO3\n", ":: KO\n", ":: KOH\n", ":: K2\n", ":: K2+\n", ":: K2CO3\n", ":: K2C2N2\n", ":: K2O\n", ":: K2O+\n", ":: K2O2\n", ":: K2O2H2\n", ":: K2SO4\n", ":: N\n", ":: N+\n", ":: N-\n", ":: NCO\n", ":: NH\n", ":: NH+\n", ":: NH2\n", ":: NH3\n", ":: NH2OH\n", ":: NH4+\n", ":: NO\n", ":: NO+\n", ":: NO2\n", ":: NO2-\n", ":: NO3\n", ":: NO3-\n", ":: N2\n", ":: N2+\n", ":: N2-\n", ":: NCN\n", ":: N2H2\n", ":: NH2NO2\n", ":: N2H4\n", ":: N2O\n", ":: N2O+\n", ":: N2O3\n", ":: N2O4\n", ":: N2O5\n", ":: N3\n", ":: N3H\n", ":: O\n", ":: O+\n", ":: O-\n", ":: OH\n", ":: OH+\n", ":: OH-\n", ":: O2\n", ":: O2+\n", ":: O2-\n", ":: O3\n", ":: S\n", ":: S+\n", ":: S-\n", ":: SH\n", ":: SH-\n", ":: SN\n", ":: SO\n", ":: SO-\n", ":: SO2\n", ":: SO2-\n", ":: SO3\n", ":: S2\n", ":: S2-\n", ":: S2O\n", ":: S3\n", ":: S4\n", ":: S5\n", ":: S6\n", ":: S7\n", ":: S8\n", ":: JP-10(g)\n", ":: Jet-A(g)\n", "Condensed Phases\n", ":: Ca(cd)\n", ":: CaCO3(cd)\n", ":: CaH2(cd)\n", ":: CaO(cd)\n", ":: Ca(OH)2(cd)\n", ":: CaS(cd)\n", ":: CaSO4(cd)\n", ":: K(cd)\n", ":: KCN(cd)\n", ":: KH(cd)\n", ":: KNO2(cd)\n", ":: KNO3(cd)\n", ":: KOH(cd)\n", ":: KO2(cd)\n", ":: K2CO3(cd)\n", ":: K2O(cd)\n", ":: K2O2(cd)\n", ":: K2S(cd)\n", ":: K2SO4(cd)\n", ":: S(cd)\n", ":: NH4NO3(cd)\n" ] } ], "source": [ "print(\"Gases\")\n", "for species in system.species():\n", " if species.aggregateState() == AggregateState.Gas:\n", " print(\":: \" + species.name())\n", "print(\"Condensed Phases\")\n", "for species in system.species():\n", " if species.aggregateState() == AggregateState.CondensedPhase:\n", " print(\":: \" + species.name())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's check how many phases and species were collected in our system:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number of species in the system: 317\n", "Number of phases in the system: 67\n" ] } ], "source": [ "print(\"Number of species in the system:\", system.species().size())\n", "print(\"Number of phases in the system:\", system.phases().size())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is an impressive number of species and phases to be able to model the combustion of black powder! \n", "\n", "```{note}\n", "By including as many gases and condensed phases as possible, Reaktoro will be able to determine those that may appear after burning black powder. For example, K{{_2}}S(cd), K{{_2}}SO{{_4}}(cd) and CaS(cd) are typically formed in the combustion process. By including them in the definition of the chemical system, the chemical equilibrium solver will be able to find positive amounts for them (i.e., the solver will identify these condensed phases as stable in equilibrium).\n", "```\n", "\n", "Keep reading to learn more about how the {{ChemicalSystem}} class plays an important role in Reaktoro!" ] } ], "metadata": { "interpreter": { "hash": "e4e8b2f3ae27709963f14fd23a6560d362beea55eaec742263828e04d814e23c" }, "kernelspec": { "display_name": "Python 3.9.7 64-bit ('reaktoro-jupyter-book': conda)", "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.10.9" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }