mirror of https://github.com/ANL-CEEESA/LLEPE
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
534 lines
36 KiB
534 lines
36 KiB
{
|
|
"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<br/>\n",
|
|
"```$ git clone https://xgitlab.cels.anl.gov/summer-2020/parameter-estimation.git```<br/>\n",
|
|
"Navigate into the folder with <br/>\n",
|
|
"```$ cd parameter-estimation```<br/>\n",
|
|
"And run <br/>\n",
|
|
"```pip install -e.```<br/>\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. <br/>\n",
|
|
"Let us explore the format of this file with pandas"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>HI(m)</th>\n",
|
|
" <th>REeq(m)</th>\n",
|
|
" <th>D(m)</th>\n",
|
|
" <th>ZI(m)</th>\n",
|
|
" <th>Zeq</th>\n",
|
|
" <th>Heq</th>\n",
|
|
" <th>REI</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>0.01</td>\n",
|
|
" <td>0.0239</td>\n",
|
|
" <td>1.0921</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>0.921696</td>\n",
|
|
" <td>0.088304</td>\n",
|
|
" <td>0.050001</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>0.01</td>\n",
|
|
" <td>0.0683</td>\n",
|
|
" <td>0.4641</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>0.904906</td>\n",
|
|
" <td>0.105094</td>\n",
|
|
" <td>0.099998</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>0.01</td>\n",
|
|
" <td>0.1170</td>\n",
|
|
" <td>0.2821</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>0.900983</td>\n",
|
|
" <td>0.109017</td>\n",
|
|
" <td>0.150006</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>0.01</td>\n",
|
|
" <td>0.1680</td>\n",
|
|
" <td>0.1905</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>0.903988</td>\n",
|
|
" <td>0.106012</td>\n",
|
|
" <td>0.200004</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>0.01</td>\n",
|
|
" <td>0.2637</td>\n",
|
|
" <td>0.1377</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>0.891066</td>\n",
|
|
" <td>0.118934</td>\n",
|
|
" <td>0.300011</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"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. <br/>\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.<br/>\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. <br/>\n",
|
|
"Please see parameter-estimation/data/xmls for file examples. <br/>\n",
|
|
"We can explore what has been loaded."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[<cantera.composite.Solution object at 0x000001B13BE190B8>, <cantera.composite.Solution object at 0x000001B13BE192E8>]\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.<br/> \n",
|
|
"The number after the thermodynamic property is the initial guess for the optimizer. <br/> \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, <br/> \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.<br/> 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. <br/> The default optimizer is from scipy.optimize.minimize with the arguments below. The optimizer optimizes a value multiplied by the initial guess. <br/> 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.<br/>\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": [
|
|
"<Figure size 432x288 with 1 Axes>"
|
|
]
|
|
},
|
|
"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
|
|
}
|