{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Fitting Arrhenius relationships to data\n", "\n", "This example shows how to fit Arrhenius relationships to data using the ArrheniusLogLinear class.\n", "\n", "We plan on adding more thermal functions in the future, so keep an eye out for updates!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import ionworkspipeline as iwp\n", "import matplotlib.pyplot as plt\n", "import pybamm\n", "import pandas as pd\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Begin by generating some synthetic data.\n", "\n", "We will show this with a test parameter with units [arb], but this could be any parameter. The units are used to process the results. We add a bit of noise to the data to make it interesting." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "R = pybamm.constants.R.value\n", "T = np.linspace(275, 325, 100)\n", "Ea_true = 50000.0\n", "A_true = 20.0\n", "T_ref = 298.15\n", "\n", "param_name = \"Test parameter [arb]\"\n", "\n", "param_val = A_true * np.exp(\n", " -Ea_true / (R * T) + Ea_true / (R * T_ref)\n", ") + np.random.normal(0, 5e-2, len(T))\n", "\n", "fig, ax = plt.subplots(1, 2, figsize=(8, 4))\n", "ax[0].scatter(T, param_val, label=\"True\", color=\"black\")\n", "ax[1].scatter(1 / T, np.log(param_val), label=\"True\", color=\"black\")\n", "ax[0].set_xlabel(\"Temperature [K]\")\n", "ax[0].set_ylabel(param_name)\n", "ax[1].set_xlabel(\"1/Temperature [1/K]\")\n", "ax[1].set_ylabel(\"ln(\" + param_name + \")\")\n", "ax[0].legend()\n", "ax[1].legend()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we can fit the Arrhenius relationship using the `ArrheniusLogLinear` class provided by `ionworkspipeline`. The class takes as input a pandas `DataFrame` with the temperature and the parameter of interest. The reference temperature is optional, and if not provided, no reference temperature is used in the fit. Running the fit returns a dict with the activation energy, the pre-exponential factor (A), the reference temperature if provided, and a function for the parameter as a function of temperature." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "arrh_fitter = iwp.calculations.ArrheniusLogLinear(\n", " pd.DataFrame({\"Temperature [K]\": T, param_name: param_val}),\n", " reference_temperature=T_ref,\n", ")\n", "param_values = arrh_fitter.run(None)\n", "print(\n", " \"Pre-exponential factor for test parameter [arb]:\",\n", " param_values[\"Pre-exponential factor for test parameter [arb]\"],\n", ")\n", "print(\"True pre-exponential factor for test parameter [arb]:\", A_true)\n", "print(\n", " \"Activation energy for test parameter [J.mol-1]:\",\n", " param_values[\"Activation energy for test parameter [J.mol-1]\"],\n", ")\n", "print(\"True activation energy for test parameter [J.mol-1]:\", Ea_true)\n", "print(\"\\n\")\n", "print(\"Full dict of results:\")\n", "print(param_values)\n", "\n", "\n", "ax[0].plot(T, param_values[\"Test parameter [arb]\"](T), label=\"Fitted\")\n", "ax[1].plot(\n", " 1 / T, [np.log(param_values[\"Test parameter [arb]\"](t)) for t in T], label=\"Fitted\"\n", ")\n", "ax[0].legend()\n", "ax[1].legend()\n", "fig" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We also provide a `plot_arrhenius` method that plots the Arrhenius relationship once the calculation has been run." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = arrh_fitter.plot_arrhenius()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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" } }, "nbformat": 4, "nbformat_minor": 2 }