{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# REEPS Tutorial - Getting started\n", "## Introduction\n", "In this notebook, you will learn how to use REEPS to fit thermodynamic parameters to experimental data and explore how well the parameters fit.\n", "## Installation\n", "In your terminal run
\n", "```$ git clone https://xgitlab.cels.anl.gov/summer-2020/parameter-estimation.git```
\n", "Navigate into the folder with
\n", "```$ cd parameter-estimation```
\n", "And run
\n", "```pip install -e.```
\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import and instantiate REEPS" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, you will need to import the package and instantiate REEPS with a few parameters." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import sys # Navigating to reeps.py since not a package yet\n", "sys.path.append('../../')\n", "from reeps import REEPS\n", "searcher_parameters = {'exp_csv_filename': '../../data/csvs/exp_data.csv',\n", " 'phases_xml_filename': '../../data/xmls/twophase.xml',\n", " 'opt_dict': {'Nd(H(A)2)3(org)': {'h0': -4.7e6}},\n", " 'phase_names': ['HCl_electrolyte', 'PC88A_liquid'],\n", " 'aq_solvent_name': 'H2O(L)',\n", " 'extractant_name': '(HA)2(org)',\n", " 'diluant_name': 'dodecane',\n", " 'complex_name': 'Nd(H(A)2)3(org)',\n", " 'rare_earth_ion_name': 'Nd+++',\n", " 'aq_solvent_rho': 1000.0,\n", " 'extractant_rho': 960.0,\n", " 'diluant_rho': 750.0}\n", "searcher = REEPS(**searcher_parameters)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Parameters explanation " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### exp_csv_filename" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "exp_csv_filename is the file name for the csv containing experimental data.
\n", "Let us explore the format of this file with pandas" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
HI(m)REeq(m)D(m)ZI(m)ZeqHeqREI
00.010.02391.092110.9216960.0883040.050001
10.010.06830.464110.9049060.1050940.099998
20.010.11700.282110.9009830.1090170.150006
30.010.16800.190510.9039880.1060120.200004
40.010.26370.137710.8910660.1189340.300011
\n", "
" ], "text/plain": [ " HI(m) REeq(m) D(m) ZI(m) Zeq Heq REI\n", "0 0.01 0.0239 1.0921 1 0.921696 0.088304 0.050001\n", "1 0.01 0.0683 0.4641 1 0.904906 0.105094 0.099998\n", "2 0.01 0.1170 0.2821 1 0.900983 0.109017 0.150006\n", "3 0.01 0.1680 0.1905 1 0.903988 0.106012 0.200004\n", "4 0.01 0.2637 0.1377 1 0.891066 0.118934 0.300011" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "exp_df = pd.read_csv(searcher_parameters['exp_csv_filename'])\n", "exp_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The rows are for experiments, and the columns are for the measured quantaties.
\n", "REEPS is looking for the ordering of these columns so it is important your experimental file has this ordering. Column names do not matter.
\n", "Below is a table explaining the meaning of the column headers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "| Column | Meaning |\n", "|---------|-----------------------------------------------------------------------------------------|\n", "| HI(m) | Initial Concentration of H+ ions (mol/L) |\n", "| REeq(m) | Equilibrium concentration of Rare Earth ions (mol/L) |\n", "| D(m) | Equilibrium Ratio between amount of rare earth elements in organic to amount in aqueous |\n", "| ZI(m) | Initial concentration of extractant (mol/L) |\n", "| Zeq | Equilibrium concentration of extractant (mol/L) |\n", "| Heq | Equilibrium concentration of H+ ions (mol/L) |\n", "| REI | Initial concentration of rare earth ions (mol/L) |" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### phases_xml_filename" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is the xml file containing information to be loaded into Cantera, the thermodynamic modeling package.
\n", "Please see parameter-estimation/data/xmls for file examples.
\n", "We can explore what has been loaded." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[, ]\n" ] } ], "source": [ "print(searcher.get_phases())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is a list of two Cantera solutions so we will dig in a little further and see what species these solutions contain." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "HCl_electrolyte\n", "['H2O(L)', 'H+', 'OH-', 'Cl-', 'Nd+++']\n", "PC88A_liquid\n", "['(HA)2(org)', 'dodecane', 'Nd(H(A)2)3(org)']\n" ] } ], "source": [ "for phase in searcher.get_phases():\n", " print(phase.name)\n", " print(phase.species_names)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can explore Cantera solutions further by visiting https://cantera.org/ and seeing Cantera's documentation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### opt_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is a dictionary that contains the information about what species and what thermodynamic properties are to be modified.
\n", "The number after the thermodynamic property is the initial guess for the optimizer.
\n", "In this example, we chose to optimize the standard enthalpy (h0) of the neodymium-PC88A complex ('Nd(H(A)2)3(org)') and give it an initial guess of -4.7e6. Thus,
\n", "```python \n", "opt_dict={'Nd(H(A)2)3(org)': {'h0': -4.7e6}}```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Say we wanted to also modify the extractant ('(HA)2(org)'), but this time change both the standard enthalpy (h0) and the molar volume (molarVolume), then the dictionary would be\n", "```python \n", "opt_dict={'Nd(H(A)2)3(org)': {'h0': -4.7e6, 'molarVolume':1.01},\n", " '(HA)2(org)': {'h0': -4.7e6, 'molarVolume':1.01}}```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### phase_names" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This a list of the phase names in the xml file and can be found in the field phase id." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Names and rhos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "| Parameter | Meaning | Example value |\n", "|---------------------|----------------------------------------------|-------------------|\n", "| aq_solvent_name | Name of solvent in aqueous phase | 'H2O(L)' |\n", "| extractant_name | Name of extractant in organic phase | '(HA)2(org)' |\n", "| diluant_name | Name of diluant in organic phase | 'dodecane' |\n", "| complex_name | Name of rare earth complex in organic phase | 'Nd(H(A)2)3(org)' |\n", "| rare_earth_ion_name | Name of rare earth ion name in aqueous phase | 'Nd+++' |\n", "| rhos | Density of species (g/L) | 1000 for 'H2O(L)' |" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the variables containing \"rho\", these parameters can be left \"None\", and molecular weight and molar volume will be used to calculate density.
However, molar volume values may be wrong and mess up calculations so it is recommended to find density values and replace the default values." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fitting thermodynamic properties to data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that the thermodynamic properties have been set, we now need to set up the optimizer.
The default optimizer is from scipy.optimize.minimize with the arguments below. The optimizer optimizes a value multiplied by the initial guess.
Say $x$ is the variable controlled by the minimizer, the value that is entering the objective function is $x\\times\\mathrm{Guess\\,value}$. So for our case, the values tested are $(4.6\\times 10^6)x$. This is more important for bounds and constraints." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "minimizer_kwargs = {\"method\": 'SLSQP',\n", " \"bounds\": [(1e-1, 1e1)],\n", " \"constraints\": (),\n", " \"options\": {'disp': True, \n", " 'maxiter': 1000, \n", " 'ftol': 1e-6}}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With the minimizer arguments defined, we can perform our fit.
\n", "This minimizes the log mean squared error between the predicted and experimental Distribution ratio (D)." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Optimization terminated successfully. (Exit mode 0)\n", " Current function value: 0.025193288852542232\n", " Iterations: 4\n", " Function evaluations: 16\n", " Gradient evaluations: 4\n", "{'Nd(H(A)2)3(org)': {'h0': -4704699.156668724}}\n" ] } ], "source": [ "est_enthalpy = searcher.fit()\n", "print(est_enthalpy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that the fit function returns an identical structure to opt_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Updating the xml" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we have our new values, let us write them to our original xml to replace the old values" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "searcher.update_xml(est_enthalpy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualization and analysis" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also see how well this new xml data fits to the experimental data with a parity plot." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "searcher.parity_plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also find what the r-squared value is. The closer to 1, the better the prediction model." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.9970803631106648\n" ] } ], "source": [ "print(searcher.r_squared())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Yay! Good job! That is an amazing fit." ] } ], "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.7" } }, "nbformat": 4, "nbformat_minor": 4 }