diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst index a5958b327b..dab8247ddf 100644 --- a/docs/source/examples/index.rst +++ b/docs/source/examples/index.rst @@ -54,6 +54,7 @@ The notebooks are organised into subfolders, and can be viewed in the galleries notebooks/models/DFN-with-particle-size-distributions.ipynb notebooks/models/DFN.ipynb notebooks/models/electrode-state-of-health.ipynb + notebooks/models/graded-electrodes.ipynb notebooks/models/half-cell.ipynb notebooks/models/jelly-roll-model.ipynb notebooks/models/latexify.ipynb diff --git a/docs/source/examples/notebooks/models/graded-electrodes.ipynb b/docs/source/examples/notebooks/models/graded-electrodes.ipynb new file mode 100644 index 0000000000..adb316ba2d --- /dev/null +++ b/docs/source/examples/notebooks/models/graded-electrodes.ipynb @@ -0,0 +1,277 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simulating graded electrodes\n", + "\n", + "In this notebook we explore how to simulate the effect of graded electrodes in the performance of a battery. Graded electrodes have a composition that varies along the thickness of the electrode, typically active material volume fraction and particle size. This variation can be used to improve the performance of the battery, for example, by increasing the power density.\n", + "\n", + "As usual, we start by importing PyBaMM." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "An NVIDIA GPU may be present on this machine, but a CUDA-enabled jaxlib is not installed. Falling back to cpu.\n" + ] + } + ], + "source": [ + "%pip install \"pybamm[plot,cite]\" -q # install PyBaMM if it is not installed\n", + "import pybamm" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We use the DFN model for the simulations and the Chen2020 parameter set. Note that we will need to modify the default Chen2020 parameter set to describe graded electrodes." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "model = pybamm.lithium_ion.DFN()\n", + "parameter_values = pybamm.ParameterValues(\"Chen2020\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will vary the porosity in both electrodes and we will try three different scenarios: constant porosity, one where lower porosity occurs near the separator and one where lower porosity occurs near the current collector. All other parameters are kept constant. The varying porosity is defined to be linear centered around the default value and with a variation of $\\pm$ 10%.\n", + "\n", + "We define the varying porosities and store them in a list so we can loop over when solving the model." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "L_n = parameter_values[\"Negative electrode thickness [m]\"]\n", + "L_s = parameter_values[\"Separator thickness [m]\"]\n", + "L_p = parameter_values[\"Positive electrode thickness [m]\"]\n", + "\n", + "eps_n_0 = parameter_values[\"Negative electrode porosity\"]\n", + "eps_p_0 = parameter_values[\"Positive electrode porosity\"]\n", + "\n", + "eps_ns = [\n", + " eps_n_0,\n", + " lambda x: eps_n_0 * (1.1 - 0.2 * (x / L_n)),\n", + " lambda x: eps_n_0 * (0.9 + 0.2 * (x / L_n)),\n", + "]\n", + "\n", + "eps_ps = [\n", + " eps_p_0,\n", + " lambda x: eps_p_0 * (0.9 - 0.2 / L_p * (L_n + L_s) + 0.2 * (x / L_p)),\n", + " lambda x: eps_p_0 * (1.1 + 0.2 / L_p * (L_n + L_s) - 0.2 * (x / L_p)),\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that the distance through the electrode is computed from the negative electrode, so parameter need to be defined accordingly. Next, we can just solve the models for the various parameter sets. We apply a fairly high C-rate to see the effect of the graded electrodes on the discharge capacity." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "solutions = []\n", + "\n", + "experiment = pybamm.Experiment([\"Discharge at 3C until 2.5 V\"])\n", + "\n", + "for eps_n, eps_p in zip(eps_ns, eps_ps):\n", + " parameter_values[\"Negative electrode porosity\"] = eps_n\n", + " parameter_values[\"Positive electrode porosity\"] = eps_p\n", + " sim = pybamm.Simulation(\n", + " model,\n", + " parameter_values=parameter_values,\n", + " experiment=experiment,\n", + " solver=pybamm.IDAKLUSolver(),\n", + " )\n", + " sol = sim.solve()\n", + " solutions.append(sol)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And plot the results:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "99f847ca09da40cba550dd02dd8281a2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(FloatSlider(value=0.0, description='t', max=673.9136958613059, step=6.7391369586130585),…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pybamm.dynamic_plot(\n", + " solutions,\n", + " labels=[\n", + " \"Constant porosity\",\n", + " \"Low porosity at separator\",\n", + " \"High porosity at separator\",\n", + " ],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We observe that, even though the average porosity is the same for the three cases the discharge capacity is much higher with the graded electrode where porosity is higher near the separator. This is because the higher porosity near the separator facilitates the ion transport and the better utilisation of the active material.\n", + "\n", + "As a sanity check we can plot the porosity profiles for the three cases and see they match what we intended." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "829b68c6b3e04e0ebe5537daabec2278", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(FloatSlider(value=0.0, description='t', max=673.9136958613059, step=6.7391369586130585),…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pybamm.dynamic_plot(\n", + " solutions,\n", + " output_variables=[\"Negative electrode porosity\", \"Positive electrode porosity\"],\n", + " labels=[\n", + " \"Constant porosity\",\n", + " \"Low porosity at separator\",\n", + " \"High porosity at separator\",\n", + " ],\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1] Joel A. E. Andersson, Joris Gillis, Greg Horn, James B. Rawlings, and Moritz Diehl. CasADi – A software framework for nonlinear optimization and optimal control. Mathematical Programming Computation, 11(1):1–36, 2019. doi:10.1007/s12532-018-0139-4.\n", + "[2] Von DAG Bruggeman. Berechnung verschiedener physikalischer konstanten von heterogenen substanzen. i. dielektrizitätskonstanten und leitfähigkeiten der mischkörper aus isotropen substanzen. Annalen der physik, 416(7):636–664, 1935.\n", + "[3] Chang-Hui Chen, Ferran Brosa Planella, Kieran O'Regan, Dominika Gastol, W. Dhammika Widanage, and Emma Kendrick. Development of Experimental Techniques for Parameterization of Multi-scale Lithium-ion Battery Models. Journal of The Electrochemical Society, 167(8):080534, 2020. doi:10.1149/1945-7111/ab9050.\n", + "[4] Marc Doyle, Thomas F. Fuller, and John Newman. Modeling of galvanostatic charge and discharge of the lithium/polymer/insertion cell. Journal of the Electrochemical society, 140(6):1526–1533, 1993. doi:10.1149/1.2221597.\n", + "[5] Charles R. Harris, K. Jarrod Millman, Stéfan J. van der Walt, Ralf Gommers, Pauli Virtanen, David Cournapeau, Eric Wieser, Julian Taylor, Sebastian Berg, Nathaniel J. Smith, and others. Array programming with NumPy. Nature, 585(7825):357–362, 2020. doi:10.1038/s41586-020-2649-2.\n", + "[6] Alan C. Hindmarsh. The PVODE and IDA algorithms. Technical Report, Lawrence Livermore National Lab., CA (US), 2000. doi:10.2172/802599.\n", + "[7] Alan C. Hindmarsh, Peter N. Brown, Keith E. Grant, Steven L. Lee, Radu Serban, Dan E. Shumaker, and Carol S. Woodward. SUNDIALS: Suite of nonlinear and differential/algebraic equation solvers. ACM Transactions on Mathematical Software (TOMS), 31(3):363–396, 2005. doi:10.1145/1089014.1089020.\n", + "[8] Peyman Mohtat, Suhak Lee, Jason B Siegel, and Anna G Stefanopoulou. Towards better estimability of electrode-specific state of health: decoding the cell expansion. Journal of Power Sources, 427:101–111, 2019.\n", + "[9] Valentin Sulzer, Scott G. Marquis, Robert Timms, Martin Robinson, and S. Jon Chapman. Python Battery Mathematical Modelling (PyBaMM). Journal of Open Research Software, 9(1):14, 2021. doi:10.5334/jors.309.\n", + "[10] Pauli Virtanen, Ralf Gommers, Travis E. Oliphant, Matt Haberland, Tyler Reddy, David Cournapeau, Evgeni Burovski, Pearu Peterson, Warren Weckesser, Jonathan Bright, and others. SciPy 1.0: fundamental algorithms for scientific computing in Python. Nature Methods, 17(3):261–272, 2020. doi:10.1038/s41592-019-0686-2.\n", + "[11] Andrew Weng, Jason B Siegel, and Anna Stefanopoulou. Differential voltage analysis for battery manufacturing process control. arXiv preprint arXiv:2303.07088, 2023.\n", + "\n" + ] + } + ], + "source": [ + "pybamm.print_citations()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "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.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}