{ "cells": [ { "cell_type": "markdown", "id": "c0f1484c", "metadata": {}, "source": [ "# Performing a chemical equilibrium calculation using equilibrium solver\n", "\n", "This tutorial demonstrates how to use Reaktoro to perform a chemical equilibrium calculation with the help of\n", "the [EquilibriumSolver](https://reaktoro.org/cpp/classReaktoro_1_1EquilibriumSolver.html) class. First, we import\n", "everything from the `reaktoro` package by" ] }, { "cell_type": "code", "execution_count": null, "id": "e864a7de", "metadata": {}, "outputs": [], "source": [ "from reaktoro import *" ] }, { "cell_type": "markdown", "id": "351866e9", "metadata": {}, "source": [ "### Initializing chemical system" ] }, { "cell_type": "markdown", "id": "72cf6d0f", "metadata": {}, "source": [ "We start from creating an object of [Database](https://reaktoro.org/cpp/classReaktoro_1_1Database.html) class to\n", "use in the initialization of the chemical system." ] }, { "cell_type": "code", "execution_count": null, "id": "88473666", "metadata": {}, "outputs": [], "source": [ "database = Database(\"supcrt98.xml\")" ] }, { "cell_type": "markdown", "id": "157ec0f9", "metadata": {}, "source": [ "Next, we define which phases and species the chemical system should have. This is done using an instance of\n", "[ChemicalEditor](https://reaktoro.org/cpp/classReaktoro_1_1ChemicalEditor.html) class." ] }, { "cell_type": "code", "execution_count": null, "id": "444aaf7b", "metadata": {}, "outputs": [], "source": [ "editor = ChemicalEditor(database)\n", "editor.addAqueousPhaseWithElementsOf(\"H2O NaCl CO2\")\n", "editor.addGaseousPhase([\"H2O(g)\", \"CO2(g)\"])\n", "editor.addMineralPhase(\"Halite\")" ] }, { "cell_type": "markdown", "id": "f9fbf5ea", "metadata": {}, "source": [ "Here, [AqueousPhase](https://reaktoro.org/cpp/classReaktoro_1_1AqueousPhase.html) is created by specifying the\n", "list of compound or substance names, i.e., H2O, NaCl, and CO2, that might not\n", "necessarily represent names of species in the database.\n", "Function [addAqueousPhaseWithElementsOf](\n", "https://reaktoro.org/cpp/classReaktoro_1_1ChemicalEditor.html#a23e44f994b87c650a949226ddc195710) will brake the list\n", "of compounds into a list of element names and the database will be similarly searched for all species that could\n", "be formed out of those elements." ] }, { "cell_type": "markdown", "id": "c33c0d3e", "metadata": {}, "source": [ "Then, [GaseousPhase](https://reaktoro.org/cpp/classReaktoro_1_1GaseousPhase.html) is composed of the names of\n", "the provided gaseous species H2O(g) and CO2(g), using function\n", "[addGaseousPhase](https://reaktoro.org/cpp/classReaktoro_1_1ChemicalEditor.html#a8ec1e3a057d794df0dd6988c84bb5d3d).\n", "These names must conform to those used in the database that was specified during the initialization of the\n", "[ChemicalEditor](https://reaktoro.org/cpp/classReaktoro_1_1ChemicalEditor.html) object, otherwise, an exception\n", "will be thrown." ] }, { "cell_type": "markdown", "id": "67f49606", "metadata": {}, "source": [ "The [MineralPhase](https://reaktoro.org/cpp/classReaktoro_1_1MineralPhase.html) object is created by specifying the\n", "names of the mineral species one by one. Analogously to the gaseous species, provided names must\n", "coincide with those used in the database (specified during the initialization of\n", "[ChemicalEditor](https://reaktoro.org/cpp/classReaktoro_1_1ChemicalEditor.html) object) ,\n", "otherwise, an exception will be thrown. In this case, the method\n", "[addMineralPhase](https://reaktoro.org/cpp/classReaktoro_1_1ChemicalEditor.html#a05b263aa9d797a105feb9b83e05e1b86)\n", "is used to create single pure mineral phases with halite." ] }, { "cell_type": "markdown", "id": "6c055a27", "metadata": {}, "source": [ "To initialize the chemical system, we use class\n", "[ChemicalSystem](https://reaktoro.org/cpp/classReaktoro_1_1ChemicalSystem.html), which requires the\n", "instance of [ChemicalEditor](https://reaktoro.org/cpp/classReaktoro_1_1ChemicalEditor.html) defined earlier." ] }, { "cell_type": "code", "execution_count": null, "id": "e4817b06", "metadata": {}, "outputs": [], "source": [ "system = ChemicalSystem(editor)" ] }, { "cell_type": "markdown", "id": "0da05c8e", "metadata": {}, "source": [ "### Equilibrium problem definition" ] }, { "cell_type": "markdown", "id": "e20384b2", "metadata": {}, "source": [ "The equilibrium problem is described by the class\n", "[EquilibriumProblem](https://reaktoro.org/cpp/classReaktoro_1_1EquilibriumProblem.html). Here, different properties,\n", "such as temperature, pressure, and amounts of compounds, can be provided." ] }, { "cell_type": "code", "execution_count": null, "id": "5cc7a1ac", "metadata": {}, "outputs": [], "source": [ "problem = EquilibriumProblem(system)\n", "problem.setTemperature(60, \"celsius\")\n", "problem.setPressure(300, \"bar\")\n", "problem.add(\"H2O\", 1, \"kg\")\n", "problem.add(\"CO2\", 100, \"g\")\n", "problem.add(\"NaCl\", 0.1, \"mol\")" ] }, { "cell_type": "markdown", "id": "a1896c75", "metadata": {}, "source": [ "In particular, we set the temperature to 60 °C and pressure to 300 bar. To equilibrate the chemical problem,\n", "we also add 1kg of water, 100 g of carbon dioxide, and 0.1 mol of sodium chloride." ] }, { "cell_type": "markdown", "id": "c18092cf", "metadata": {}, "source": [ "> *See tutorials [**ChemicalEditor**](cl.chemical-editor.ipynb) and [**ChemicalSystem**](cl.chemical-system.ipynb)\n", "> for more detailed explanation of capabilities of these classes*." ] }, { "cell_type": "markdown", "id": "484240e6", "metadata": {}, "source": [ "### Equilibrium solver definition" ] }, { "cell_type": "markdown", "id": "c12b1f25", "metadata": {}, "source": [ "The temperature, pressure, and mole amounts of the elements can be obtained from the definition of equilibrium\n", "problem." ] }, { "cell_type": "code", "execution_count": null, "id": "eb96e27a", "metadata": {}, "outputs": [], "source": [ "T = problem.temperature()\n", "P = problem.pressure()\n", "b = problem.elementAmounts()" ] }, { "cell_type": "markdown", "id": "da98ac8a", "metadata": {}, "source": [ "Next, we create an object of [EquilibriumSolver](https://reaktoro.org/cpp/classReaktoro_1_1EquilibriumSolver.html)\n", "class that can be reused many times for equilibrium simulations." ] }, { "cell_type": "code", "execution_count": null, "id": "106ac958", "metadata": {}, "outputs": [], "source": [ "solver = EquilibriumSolver(system)" ] }, { "cell_type": "markdown", "id": "fb4524c9", "metadata": {}, "source": [ "> For more detailed overview on the functionality of the class\n", "> [EquilibriumSolver](https://reaktoro.org/cpp/classReaktoro_1_1EquilibriumSolver.html),\n", "> please check the tutorial [**EquilibriumSolver**](cl.equilibrium-solver.py)." ] }, { "cell_type": "markdown", "id": "3eeb3c7a", "metadata": {}, "source": [ "Similarly, an object of [ChemicalState](https://reaktoro.org/cpp/classReaktoro_1_1ChemicalState.html) class,\n", "which stores the equilibrium state of the system, can be created." ] }, { "cell_type": "code", "execution_count": null, "id": "a30de570", "metadata": {}, "outputs": [], "source": [ "state = ChemicalState(system)" ] }, { "cell_type": "markdown", "id": "ee731777", "metadata": {}, "source": [ "### Equilibration at 60 °C" ] }, { "cell_type": "markdown", "id": "831aedf4", "metadata": {}, "source": [ "Using method [EquilibriumSolver::solve](https://reaktoro.org/cpp/classReaktoro_1_1EquilibriumSolver.html#ab01c678651bacb079f8f436c9a3a5148),\n", "the equilibrium state with given *(T, P, b)* inputs is generated and stored in the object `state`." ] }, { "cell_type": "code", "execution_count": null, "id": "3678fe35", "metadata": {}, "outputs": [], "source": [ "solver.solve(state, T, P, b)" ] }, { "cell_type": "markdown", "id": "bb2fec50", "metadata": {}, "source": [ "Here, the object `state` serves as the initial guess and the final state of the equilibrium calculation. If known,\n", "the temperature must be provided in Kelvin, and the pressure is expected in Pascal. Vector `b` provides the molar\n", "amounts of the elements in the equilibrium partition. Alternatively, one can call this method with the given\n", "equilibrium problem." ] }, { "cell_type": "markdown", "id": "946399a7", "metadata": {}, "source": [ "To save the calculated chemical equilibrium state into the text-file, we use the method\n", "[ChemicalState::output](https://reaktoro.org/cpp/classReaktoro_1_1ChemicalState.html#ae5f2706f5be6e6856360a2f1073931e2)." ] }, { "cell_type": "code", "execution_count": null, "id": "dc7307c4", "metadata": {}, "outputs": [], "source": [ "state.output('state-T-60.txt')" ] }, { "cell_type": "markdown", "id": "71d84b00", "metadata": {}, "source": [ "In the saved file, one can note that the amount of halite is of the order $10^{-21}$, which indicates its\n", "dissolution in sodium chloride brine." ] }, { "cell_type": "markdown", "id": "5f8fae19", "metadata": {}, "source": [ "### Equilibration at 70 °C" ] }, { "cell_type": "markdown", "id": "9ced50f1", "metadata": {}, "source": [ "Calculate the new equilibrium state at temperature increased by 10 °C. For that, we use the previous\n", "equilibrium state as the initial guess for improved performance." ] }, { "cell_type": "code", "execution_count": null, "id": "841169be", "metadata": {}, "outputs": [], "source": [ "solver.solve(state, T + 10.0, P, b)" ] }, { "cell_type": "markdown", "id": "fbf7aa8e", "metadata": {}, "source": [ "Save newly calculated chemical equilibrium state with T = 70 °C into the text-file." ] }, { "cell_type": "code", "execution_count": null, "id": "d8b4693e", "metadata": {}, "outputs": [], "source": [ "state.output('state-T-70.txt')" ] }, { "cell_type": "markdown", "id": "86c1b14c", "metadata": {}, "source": [ "In comparison to chemical speciation obtained for equilibrium calculation at 60 °C,\n", "the ionic strength, reduction potential, and alkalinity slightly decrease, whereas ph slightly increases." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 5 }