{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Pure substance phase diagrams\n", "\n", "## Goal of this notebook\n", "\n", "- Learn how to generate and work with phase diagrams.\n", "- Learn what `PhaseEquilibrium` objects are and how to use them." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from feos.si import *\n", "from feos.pcsaft import *\n", "from feos.eos import *\n", "\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "\n", "sns.set_context('talk')\n", "sns.set_palette('Dark2')\n", "sns.set_style('ticks')\n", "colors = sns.palettes.color_palette('Dark2', 8)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Read parameters from json for a single substance and generate `PcSaft` object" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "|component|molarweight|$m$|$\\sigma$|$\\varepsilon$|$\\mu$|$Q$|$\\kappa_{AB}$|$\\varepsilon_{AB}$|$N_A$|$N_B$|\n", "|-|-|-|-|-|-|-|-|-|-|-|\n", "|hexane|86.177|3.0576|3.7983|236.77|0|0|0|0|1|1|" ], "text/plain": [ "PcSaftParameters(\n", "\tmolarweight=[86.177]\n", "\tm=[3.0576]\n", "\tsigma=[3.7983]\n", "\tepsilon_k=[236.77]\n", ")" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "parameters = PcSaftParameters.from_json(\n", " ['hexane'], \n", " '../parameters/pcsaft/gross2001.json'\n", ")\n", "parameters" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "pcsaft = EquationOfState.pcsaft(parameters)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## The `PhaseDiagram` object\n", "\n", "A `PhaseDiagram` object contains multiple thermodyanmic states at phase equilibrium.\n", "**For a single substance** it can be constructed via the `PhaseDiagram.pure` method by providing \n", "\n", "- an equation of state,\n", "- the minimum temperature, and\n", "- the number of points to compute.\n", "\n", "The points are evenly distributed between the defined minimum temperature and the critical temperature which is either computed (default) or can be provided via the `critical_temperature` argument.\n", "\n", "Furthermore, we can define options for the numerics:\n", "- `max_iter` to define the maximum number of iterations for the phase equilibrium calculations, and\n", "- `tol` to set the tolerance used for deterimation of phase equilibria.\n", "\n", "A `Verbosity` object can be provided via the `verbosity` argument to print intermediate calculations to the screen.\n", "\n", "Starting from the minimum temperature, phase equilibria are computed in sequence using prior results (i.e. at prior temperature) as input for the next iteration." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "phase_diagram = PhaseDiagram.pure(pcsaft, min_temperature=200*KELVIN, npoints=501)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "|temperature|density|\n", "|-|-|\n", "|200.00000 K|12.21572 mmol/m³|" ], "text/plain": [ "T = 200.00000 K, ρ = 12.21572 mmol/m³" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "phase_diagram.vapor[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Stored information\n", "\n", "A `PhaseDiagram` object contains the following *fields*:\n", "\n", "- `states`: a list (with length of `npoints`) of `PhaseEquilibrium` objects at the different temperatures,\n", "- `vapor` and `liquid`: so-called `StateVec` objects that can be used to compute properties for the vapor and liquid phase, respectively.\n", "\n", "The `to_dict` *method* can be used to conveniently generate a `pandas.DataFrame` object (see below)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Building a `pandas.DataFrame`: the `to_dict` method\n", "\n", "\n", "The `PhaseDiagramPure` object contains some physical properties (such as densities, temperatures and pressures) as well as the `PhaseEquilibrium` objects at each temperature.\n", "\n", "Before we take a look at these objects, a useful tool when working with phase diagrams is the `to_dict` method. It generates a Python dictionary of some properties (with hard-coded units, see the docstring of `to_dict`). This dictionary can readily be used to generate a `pandas.DataFrame`." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | molar enthalpy vapor | \n", "temperature | \n", "density liquid | \n", "density vapor | \n", "molar enthalpy liquid | \n", "pressure | \n", "molar entropy vapor | \n", "molar entropy liquid | \n", "
---|---|---|---|---|---|---|---|---|
0 | \n", "-16.735400 | \n", "200.000000 | \n", "8539.589591 | \n", "0.012216 | \n", "-54.057307 | \n", "20.312763 | \n", "0.003135 | \n", "-0.183475 | \n", "
1 | \n", "-16.639176 | \n", "200.638669 | \n", "8532.663964 | \n", "0.013078 | \n", "-53.920803 | \n", "21.816282 | \n", "0.003021 | \n", "-0.182794 | \n", "
2 | \n", "-16.542786 | \n", "201.277337 | \n", "8525.749142 | \n", "0.013994 | \n", "-53.784188 | \n", "23.418684 | \n", "0.002912 | \n", "-0.182114 | \n", "
3 | \n", "-16.446230 | \n", "201.916006 | \n", "8518.845002 | \n", "0.014967 | \n", "-53.647463 | \n", "25.125608 | \n", "0.002806 | \n", "-0.181436 | \n", "
4 | \n", "-16.349508 | \n", "202.554674 | \n", "8511.951422 | \n", "0.015999 | \n", "-53.510626 | \n", "26.942961 | \n", "0.002703 | \n", "-0.180759 | \n", "