From a7d476ea4f21a64d1cf3a39f8bc687035b39621d Mon Sep 17 00:00:00 2001 From: Ferran Brosa Planella Date: Mon, 7 Oct 2024 20:24:10 +0100 Subject: [PATCH] Implement sodium-ion DFN (#4451) * add sodium-ion model, parameters and examples * update citation keys to be consistent * rename electrolyte conductivity from kappa to sigma * add tests for sodium ion * fix doctests * fix doctest * remove accidentally added example * commented better the volume fraction * write volume fractions as a single number, not a substraction * improve basic tests * update CHANGELOG --------- Co-authored-by: Eric G. Kratz --- CHANGELOG.md | 1 + docs/source/examples/index.rst | 1 + .../notebooks/models/sodium-ion.ipynb | 185 +++++++ pyproject.toml | 1 + src/pybamm/CITATIONS.bib | 459 +++++++++--------- src/pybamm/__init__.py | 1 + src/pybamm/input/parameters/__init__.py | 2 +- .../input/parameters/lithium_ion/Ai2020.py | 6 +- .../input/parameters/lithium_ion/Chen2020.py | 4 +- .../input/parameters/lithium_ion/Ecker2015.py | 4 +- .../parameters/lithium_ion/Marquis2019.py | 4 +- .../parameters/lithium_ion/Mohtat2020.py | 4 +- .../parameters/lithium_ion/NCA_Kim2011.py | 4 +- .../parameters/lithium_ion/ORegan2022.py | 2 +- .../parameters/lithium_ion/Ramadass2004.py | 2 +- .../input/parameters/lithium_ion/Xu2019.py | 4 +- .../parameters/sodium_ion/Chayambuka2022.py | 341 +++++++++++++ .../input/parameters/sodium_ion/__init__.py | 1 + .../input/parameters/sodium_ion/data/D_e.csv | 14 + .../input/parameters/sodium_ion/data/D_n.csv | 40 ++ .../input/parameters/sodium_ion/data/D_p.csv | 35 ++ .../input/parameters/sodium_ion/data/U_n.csv | 21 + .../input/parameters/sodium_ion/data/U_p.csv | 28 ++ .../input/parameters/sodium_ion/data/k_n.csv | 32 ++ .../input/parameters/sodium_ion/data/k_p.csv | 24 + .../parameters/sodium_ion/data/sigma_e.csv | 6 + .../models/full_battery_models/__init__.py | 2 +- .../sodium_ion/__init__.py | 6 + .../sodium_ion/basic_dfn.py | 273 +++++++++++ .../submodels/thermal/surface/lumped.py | 2 +- .../transport_efficiency/bruggeman.py | 6 +- .../cation_exchange_membrane.py | 6 +- .../heterogeneous_catalyst.py | 6 +- .../hyperbola_of_revolution.py | 6 +- .../transport_efficiency/ordered_packing.py | 6 +- .../overlapping_spheres.py | 6 +- .../random_overlapping_cylinders.py | 6 +- src/pybamm/parameters/parameter_sets.py | 4 +- src/pybamm/solvers/jax_bdf_solver.py | 20 +- src/pybamm/spatial_methods/spectral_volume.py | 2 +- .../test_lithium_ion/test_basic_models.py | 11 +- .../test_sodium_ion/__init__.py | 0 .../test_sodium_ion/test_basic_models.py | 34 ++ .../test_sodium_ion/__init__.py | 0 .../test_sodium_ion/test_basic_models.py | 14 + .../test_Chayambuka2022.py | 41 ++ 46 files changed, 1402 insertions(+), 275 deletions(-) create mode 100644 docs/source/examples/notebooks/models/sodium-ion.ipynb create mode 100644 src/pybamm/input/parameters/sodium_ion/Chayambuka2022.py create mode 100644 src/pybamm/input/parameters/sodium_ion/__init__.py create mode 100755 src/pybamm/input/parameters/sodium_ion/data/D_e.csv create mode 100755 src/pybamm/input/parameters/sodium_ion/data/D_n.csv create mode 100755 src/pybamm/input/parameters/sodium_ion/data/D_p.csv create mode 100755 src/pybamm/input/parameters/sodium_ion/data/U_n.csv create mode 100755 src/pybamm/input/parameters/sodium_ion/data/U_p.csv create mode 100755 src/pybamm/input/parameters/sodium_ion/data/k_n.csv create mode 100755 src/pybamm/input/parameters/sodium_ion/data/k_p.csv create mode 100644 src/pybamm/input/parameters/sodium_ion/data/sigma_e.csv create mode 100644 src/pybamm/models/full_battery_models/sodium_ion/__init__.py create mode 100644 src/pybamm/models/full_battery_models/sodium_ion/basic_dfn.py create mode 100644 tests/integration/test_models/test_full_battery_models/test_sodium_ion/__init__.py create mode 100644 tests/integration/test_models/test_full_battery_models/test_sodium_ion/test_basic_models.py create mode 100644 tests/unit/test_models/test_full_battery_models/test_sodium_ion/__init__.py create mode 100644 tests/unit/test_models/test_full_battery_models/test_sodium_ion/test_basic_models.py create mode 100644 tests/unit/test_parameters/test_parameter_sets/test_Chayambuka2022.py diff --git a/CHANGELOG.md b/CHANGELOG.md index fd590fbc12..8ffc210a74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Features - Added Hermite interpolation to the (`IDAKLUSolver`) that improves the accuracy and performance of post-processing variables. ([#4464](https://github.com/pybamm-team/PyBaMM/pull/4464)) +- Added `BasicDFN` model for sodium-ion batteries ([#4451](https://github.com/pybamm-team/PyBaMM/pull/4451)) - Added sensitivity calculation support for `pybamm.Simulation` and `pybamm.Experiment` ([#4415](https://github.com/pybamm-team/PyBaMM/pull/4415)) - Added OpenMP parallelization to IDAKLU solver for lists of input parameters ([#4449](https://github.com/pybamm-team/PyBaMM/pull/4449)) - Added phase-dependent particle options to LAM diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst index dab8247ddf..3f77578ef5 100644 --- a/docs/source/examples/index.rst +++ b/docs/source/examples/index.rst @@ -68,6 +68,7 @@ The notebooks are organised into subfolders, and can be viewed in the galleries notebooks/models/SEI-on-cracks.ipynb notebooks/models/simulate-3E-cell.ipynb notebooks/models/simulating-ORegan-2022-parameter-set.ipynb + notebooks/models/sodium-ion.ipynb notebooks/models/SPM.ipynb notebooks/models/SPMe.ipynb notebooks/models/submodel_cracking_DFN_or_SPM.ipynb diff --git a/docs/source/examples/notebooks/models/sodium-ion.ipynb b/docs/source/examples/notebooks/models/sodium-ion.ipynb new file mode 100644 index 0000000000..671e7923e9 --- /dev/null +++ b/docs/source/examples/notebooks/models/sodium-ion.ipynb @@ -0,0 +1,185 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# DFN model for sodium-ion batteries\n", + "\n", + "In this notebook we use the DFN model to simulate sodium-ion batteries. The parameters are based on the article\n", + "> K. Chayambuka, G. Mulder, D.L. Danilov, P.H.L. Notten, Physics-based modeling of sodium-ion batteries part II. Model and validation, Electrochimica Acta 404 (2022) 139764. https://doi.org/10.1016/j.electacta.2021.139764.\n", + "\n", + "However, the specific values (including the data for the interpolants) are taken from the COMSOL implementation presented in [this example](https://www.comsol.com/model/1d-isothermal-sodium-ion-battery-117341). As usual, we start by importing PyBaMM." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "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": [ + "import pybamm" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We now need to define the model. In this case we take the `BasicDFN` model for sodium-ion batteries (note how it is called from the `pybamm.sodium_ion` submodule). Note that, at the moment, the model is identical to the one for lithium-ion batteries, but uses different parameter values." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "model = pybamm.sodium_ion.BasicDFN()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In order to replicate the results in the COMSOL example, we discharge at different C-rates and compare the solutions. We loop over the C-rate dictionary and solve the model for each C-rate. We append the solutions into a list so we can later plots the results." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8ca3353c637e48d28c3b02f42d25fa03", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(FloatSlider(value=0.0, description='t', max=10.80914150213347, step=0.1080914150213347),…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "C_rates = [1 / 12, 5 / 12, 10 / 12, 1]\n", + "solutions = []\n", + "\n", + "for C_rate in C_rates:\n", + " sim = pybamm.Simulation(model, solver=pybamm.IDAKLUSolver(), C_rate=C_rate)\n", + " sol = sim.solve([0, 4000 / C_rate])\n", + " solutions.append(sol)\n", + "\n", + "pybamm.dynamic_plot(solutions)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now perform a manual plot of voltage versus capacity, to compare the results with the COMSOL example." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "for solution, C_rate in zip(solutions, C_rates):\n", + " capacity = [i * 1000 for i in solution[\"Discharge capacity [A.h]\"].entries]\n", + " voltage = solution[\"Voltage [V]\"].entries\n", + " plt.plot(capacity, voltage, label=f\"{(12 * C_rate)} A.m-2\")\n", + "\n", + "plt.xlabel(\"Discharge Capacity [mA.h]\")\n", + "plt.ylabel(\"Voltage [V]\");" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "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] Kudakwashe Chayambuka, Grietus Mulder, Dmitri L Danilov, and Peter HL Notten. Physics-based modeling of sodium-ion batteries part ii. model and validation. Electrochimica Acta, 404:139764, 2022.\n", + "[3] 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", + "[4] Alan C. Hindmarsh. The PVODE and IDA algorithms. Technical Report, Lawrence Livermore National Lab., CA (US), 2000. doi:10.2172/802599.\n", + "[5] 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", + "[6] Scott G. Marquis, Valentin Sulzer, Robert Timms, Colin P. Please, and S. Jon Chapman. An asymptotic derivation of a single particle model with electrolyte. Journal of The Electrochemical Society, 166(15):A3693–A3706, 2019. doi:10.1149/2.0341915jes.\n", + "[7] 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", + "\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 +} diff --git a/pyproject.toml b/pyproject.toml index a70f712e3e..1db7c927a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -152,6 +152,7 @@ Ramadass2004 = "pybamm.input.parameters.lithium_ion.Ramadass2004:get_parameter_v Xu2019 = "pybamm.input.parameters.lithium_ion.Xu2019:get_parameter_values" ECM_Example = "pybamm.input.parameters.ecm.example_set:get_parameter_values" MSMR_Example = "pybamm.input.parameters.lithium_ion.MSMR_example_set:get_parameter_values" +Chayambuka2022 = "pybamm.input.parameters.sodium_ion.Chayambuka2022:get_parameter_values" [tool.setuptools] include-package-data = true diff --git a/src/pybamm/CITATIONS.bib b/src/pybamm/CITATIONS.bib index 3d853738b4..26919f7c66 100644 --- a/src/pybamm/CITATIONS.bib +++ b/src/pybamm/CITATIONS.bib @@ -22,6 +22,17 @@ @article{Ai2022 author = {Weilong Ai and Niall Kirkaldy and Yang Jiang and Gregory Offer and Huizhi Wang and Billy Wu}, } +@article{Akanni1987, + title={Effective transport coefficients in heterogeneous media}, + author={Akanni, KA and Evans, JW and Abramson, IS}, + journal={Chemical Engineering Science}, + volume={42}, + number={8}, + pages={1945--1954}, + year={1987}, + publisher={Elsevier} +} + @article{Andersson2019, author = {Andersson, Joel A. E. and Gillis, Joris and Horn, Greg and Rawlings, James B. and Diehl, Moritz}, @@ -47,6 +58,39 @@ @article{Baker2018 publisher={IOP Publishing} } +@article{Baltensperger2003, + title={Spectral differencing with a twist}, + author={Baltensperger, Richard and Trummer, Manfred R}, + journal={SIAM journal on scientific computing}, + volume={24}, + number={5}, + pages={1465--1487}, + year={2003}, + publisher={SIAM} +} + +@article{Barletta2022thevenin, + title={Th{\'e}venin’s Battery Model Parameter Estimation Based on Simulink}, + author={Barletta, Giulio and DiPrima, Piera and Papurello, Davide}, + journal={Energies}, + volume={15}, + number={17}, + pages={6207}, + year={2022}, + publisher={MDPI} +} + +@article{Beeckman1990, + title={Mathematical description of heterogeneous materials}, + author={Beeckman, JW}, + journal={Chemical engineering science}, + volume={45}, + number={8}, + pages={2603--2610}, + year={1990}, + publisher={Elsevier} +} + @article{BrosaPlanella2021, title = {Systematic derivation and validation of a reduced thermal-electrochemical model for lithium-ion batteries using asymptotic methods}, author = {Brosa Planella, Ferran and Sheikh, Muhammad and Widanage, W. Dhammika}, @@ -70,6 +114,38 @@ @article{BrosaPlanella2022 doi = {}, } +@article{Bruggeman1935, + title={Berechnung verschiedener physikalischer Konstanten von heterogenen Substanzen. I. Dielektrizit{\"a}tskonstanten und Leitf{\"a}higkeiten der Mischk{\"o}rper aus isotropen Substanzen}, + author={Bruggeman, Von DAG}, + journal={Annalen der physik}, + volume={416}, + number={7}, + pages={636--664}, + year={1935}, + publisher={Wiley Online Library} +} + +@article{Byrne1975, + title={A polyalgorithm for the numerical solution of ordinary differential equations}, + author={Byrne, George D. and Hindmarsh, Alan C.}, + journal={ACM Transactions on Mathematical Software (TOMS)}, + volume={1}, + number={1}, + pages={71--96}, + year={1975}, + publisher={ACM New York, NY, USA} +} + +@article{Chayambuka2022, + title={Physics-based modeling of sodium-ion batteries part II. Model and validation}, + author={Chayambuka, Kudakwashe and Mulder, Grietus and Danilov, Dmitri L and Notten, Peter HL}, + journal={Electrochimica Acta}, + volume={404}, + pages={139764}, + year={2022}, + publisher={Elsevier} +} + @article{Chen2020, author = {Chen, Chang-Hui and Brosa Planella, Ferran and O'Regan, Kieran and Gastol, Dominika and Widanage, W. Dhammika and Kendrick, Emma}, title = {{Development of Experimental Techniques for Parameterization of Multi-scale Lithium-ion Battery Models}}, @@ -140,6 +216,16 @@ @article{Ecker2015ii doi = {10.1149/2.0541509jes}, } +@article{Fan2022, + title={Data-driven identification of lithium-ion batteries: A nonlinear equivalent circuit model with diffusion dynamics}, + author={Fan, Chuanxin and O’Regan, Kieran and Li, Liuying and Higgins, Matthew D and Kendrick, Emma and Widanage, Widanalage D}, + journal={Applied Energy}, + volume={321}, + pages={119336}, + year={2022}, + publisher={Elsevier} +} + @article{Gustafsson2020, doi = {10.21105/joss.02369}, year = {2020}, @@ -152,6 +238,13 @@ @article{Gustafsson2020 journal = {Journal of Open Source Software}, } +@book{Hairer1993, + title={Solving ordinary differential equations. 1, Nonstiff problems}, + author={Hairer, Ernst and N{\o}rsett, Syvert P and Wanner, Gerhard}, + year={1993}, + publisher={Springer-Vlg} +} + @article{Hales2019, title={The cell cooling coefficient: a standard to define heat rejection from lithium-ion batteries}, author={Hales, Alastair and Diaz, Laura Bravo and Marzook, Mohamed Waseem and Zhao, Yan and Patel, Yatish and Offer, Gregory}, @@ -252,7 +345,18 @@ @article{Lain2019 doi = {10.3390/batteries5040064}, } -@article{lin2014lumped, +@article{Landesfeind2019, + title={Temperature and concentration dependence of the ionic transport properties of lithium-ion battery electrolytes}, + author={Landesfeind, Johannes and Gasteiger, Hubert A}, + journal={Journal of The Electrochemical Society}, + volume={166}, + number={14}, + pages={A3079--A3097}, + year={2019}, + publisher={The Electrochemical Society} +} + +@article{Lin2014, title={A lumped-parameter electro-thermal model for cylindrical batteries}, author={Lin, Xinfan and Perez, Hector E and Mohan, Shankar and Siegel, Jason B and Stefanopoulou, Anna G and Ding, Yi and Castanier, Matthew P}, journal={Journal of Power Sources}, @@ -262,6 +366,17 @@ @article{lin2014lumped publisher={Elsevier} } +@article{Mackie1955, + title={The diffusion of electrolytes in a cation-exchange resin membrane I. Theoretical}, + author={Mackie, JS and Meares, P}, + journal={Proceedings of the Royal Society of London. Series A. Mathematical and Physical Sciences}, + volume={232}, + number={1191}, + pages={498--509}, + year={1955}, + publisher={The Royal Society London} +} + @article{Marquis2019, title = {{An asymptotic derivation of a single particle model with electrolyte}}, author = {Marquis, Scott G. and Sulzer, Valentin and Timms, Robert and Please, Colin P. and Chapman, S. Jon}, @@ -321,6 +436,17 @@ @article{Newman1962 publisher={IOP Publishing} } +@article{Nieto2012, +author = {Nieto, Nerea and Diaz, Luis and Gastelurrutia, Jon and Alava, Isabel and Blanco, Francisco and Ramos, Juan and Rivas, Alejandro}, +year = {2012}, +month = {11}, +pages = {A212-A217}, +title = {Thermal Modeling of Large Format Lithium-Ion Cells}, +volume = {160}, +journal = {Journal of the Electrochemical Society}, +doi = {10.1149/2.042302jes} +} + @article{Nyman2008, title={Electrochemical characterisation and modelling of the mass transport phenomena in LiPF6--EC--EMC electrolyte}, author={Nyman, Andreas and Behm, M{\aa}rten and Lindbergh, G{\"o}ran}, @@ -370,6 +496,28 @@ @article{ORegan2022 doi = {10.1016/j.electacta.2022.140700}, } +@article{Petersen1958, + title={Diffusion in a pore of varying cross section}, + author={Petersen, EE}, + journal={AIChE Journal}, + volume={4}, + number={3}, + pages={343--345}, + year={1958}, + publisher={Wiley Online Library} +} + +@article{Ploehn2004, + title={Solvent diffusion model for aging of lithium-ion battery cells}, + author={Ploehn, Harry J and Ramadass, Premanand and White, Ralph E}, + journal={Journal of The Electrochemical Society}, + volume={151}, + number={3}, + pages={A456}, + year={2004}, + publisher={IOP Publishing} +} + @article{Prada2013, title = {{A simplified electrochemical and thermal aging model of LiFePO4-graphite Li-ion batteries: power and capacity fade simulations}}, author = {Prada, Eric and Di Domenico, D. and Creff, Y. and Bernard, J. and Sauvant-Moynot, Val{\'{e}}rie and Huet, Fran{\c{c}}ois}, @@ -439,6 +587,61 @@ @article{Richardson2021 doi = {10.1016/j.electacta.2021.138909}, } +@article{Rieger2016, + title={A new method to model the thickness change of a commercial pouch cell during discharge}, + author={Rieger, Bernhard and Erhard, Simon V and Rumpf, Katharina and Jossen, Andreas}, + journal={Journal of The Electrochemical Society}, + volume={163}, + number={8}, + pages={A1566}, + year={2016}, + publisher={IOP Publishing} +} + +@article{Safari2008, + title={Multimodal physics-based aging model for life prediction of Li-ion batteries}, + author={Safari, M and Morcrette, Mathieu and Teyssot, A and Delacourt, Charles}, + journal={Journal of The Electrochemical Society}, + volume={156}, + number={3}, + pages={A145}, + year={2008}, + publisher={IOP Publishing} +} + +@article{Shampine1997, + title={The matlab ode suite}, + author={Shampine, Lawrence F and Reichelt, Mark W}, + journal={SIAM journal on scientific computing}, + volume={18}, + number={1}, + pages={1--22}, + year={1997}, + publisher={SIAM} +} + +@article{Shen2007, + title={Critical review of the impact of tortuosity on diffusion}, + author={Shen, Lihua and Chen, Zhangxin}, + journal={Chemical Engineering Science}, + volume={62}, + number={14}, + pages={3748--3755}, + year={2007}, + publisher={Elsevier} +} + +@article{Single2018, + title={Identifying the mechanism of continued growth of the solid--electrolyte interphase}, + author={Single, Fabian and Latz, Arnulf and Horstmann, Birger}, + journal={ChemSusChem}, + volume={11}, + number={12}, + pages={1950--1955}, + year={2018}, + publisher={Wiley Online Library} +} + @article{Sripad2020, title={Kinetics of lithium electrodeposition and stripping}, author={Sripad, Shashank and Korff, Daniel and DeCaluwe, Steven C and Viswanathan, Venkatasubramanian}, @@ -510,6 +713,17 @@ @article{Timms2021 doi = {10.1137/20M1336898}, } +@article{Tomadakis1993, + title={Transport properties of random arrays of freely overlapping cylinders with various orientation distributions}, + author={Tomadakis, Manolis M and Sotirchos, Stratis V}, + journal={The Journal of chemical physics}, + volume={98}, + number={1}, + pages={616--626}, + year={1993}, + publisher={American Institute of Physics} +} + @article{Valoen2005, title={Transport properties of LiPF6-based Li-ion battery electrolytes}, author={Val{\o}en, Lars Ole and Reimers, Jan N}, @@ -556,6 +770,17 @@ @article{Wang2002 doi = {10.1006/jcph.2002.7041}, } +@article{Weissberg1963, + title={Effective diffusion coefficient in porous media}, + author={Weissberg, Harold L}, + journal={Journal of Applied Physics}, + volume={34}, + number={9}, + pages={2636--2639}, + year={1963}, + publisher={American Institute of Physics} +} + @article{Weng2023, title={Differential voltage analysis for battery manufacturing process control}, author={Weng, Andrew and Siegel, Jason B and Stefanopoulou, Anna}, @@ -563,6 +788,19 @@ @article{Weng2023 year={2023} } +@article{Wycisk2022, + title = {Modified Plett-model for modeling voltage hysteresis in lithium-ion cells}, + journal = {Journal of Energy Storage}, + volume = {52}, + pages = {105016}, + year = {2022}, + issn = {2352-152X}, + doi = {https://doi.org/10.1016/j.est.2022.105016}, + url = {https://www.sciencedirect.com/science/article/pii/S2352152X22010192}, + author = {Dominik Wycisk and Marc Oldenburger and Marc Gerry Stoye and Toni Mrkonjic and Arnulf Latz}, + keywords = {Lithium-ion battery, Voltage hysteresis, Plett-model, Silicon–graphite anode}, +} + @article{Xu2019, title={Evolution of Dead Lithium Growth in Lithium Metal Batteries: Experimentally Validated Model of the Apparent Capacity Loss}, author={Xu, Shanshan and Chen, Kuan-Hung and Dasgupta, Neil P and Siegel, Jason B and Stefanopoulou, Anna G}, @@ -595,222 +833,3 @@ @article{Zhao2018 year={2018}, publisher={IOP Publishing} } - -@article{Barletta2022thevenin, - title={Th{\'e}venin’s Battery Model Parameter Estimation Based on Simulink}, - author={Barletta, Giulio and DiPrima, Piera and Papurello, Davide}, - journal={Energies}, - volume={15}, - number={17}, - pages={6207}, - year={2022}, - publisher={MDPI} -} - -@article{Nieto2012, -author = {Nieto, Nerea and Diaz, Luis and Gastelurrutia, Jon and Alava, Isabel and Blanco, Francisco and Ramos, Juan and Rivas, Alejandro}, -year = {2012}, -month = {11}, -pages = {A212-A217}, -title = {Thermal Modeling of Large Format Lithium-Ion Cells}, -volume = {160}, -journal = {Journal of the Electrochemical Society}, -doi = {10.1149/2.042302jes} -} - -@article{shampine1997matlab, - title={The matlab ode suite}, - author={Shampine, Lawrence F and Reichelt, Mark W}, - journal={SIAM journal on scientific computing}, - volume={18}, - number={1}, - pages={1--22}, - year={1997}, - publisher={SIAM} -} - -@article{byrne1975polyalgorithm, - title={A polyalgorithm for the numerical solution of ordinary differential equations}, - author={Byrne, George D. and Hindmarsh, Alan C.}, - journal={ACM Transactions on Mathematical Software (TOMS)}, - volume={1}, - number={1}, - pages={71--96}, - year={1975}, - publisher={ACM New York, NY, USA} -} - -@book{hairer1993solving, - title={Solving ordinary differential equations. 1, Nonstiff problems}, - author={Hairer, Ernst and N{\o}rsett, Syvert P and Wanner, Gerhard}, - year={1993}, - publisher={Springer-Vlg} -} - -@article{baltensperger2003spectral, - title={Spectral differencing with a twist}, - author={Baltensperger, Richard and Trummer, Manfred R}, - journal={SIAM journal on scientific computing}, - volume={24}, - number={5}, - pages={1465--1487}, - year={2003}, - publisher={SIAM} -} - -@article{rieger2016new, - title={A new method to model the thickness change of a commercial pouch cell during discharge}, - author={Rieger, Bernhard and Erhard, Simon V and Rumpf, Katharina and Jossen, Andreas}, - journal={Journal of The Electrochemical Society}, - volume={163}, - number={8}, - pages={A1566}, - year={2016}, - publisher={IOP Publishing} -} - -@article{ploehn2004solvent, - title={Solvent diffusion model for aging of lithium-ion battery cells}, - author={Ploehn, Harry J and Ramadass, Premanand and White, Ralph E}, - journal={Journal of The Electrochemical Society}, - volume={151}, - number={3}, - pages={A456}, - year={2004}, - publisher={IOP Publishing} -} - -@article{single2018identifying, - title={Identifying the mechanism of continued growth of the solid--electrolyte interphase}, - author={Single, Fabian and Latz, Arnulf and Horstmann, Birger}, - journal={ChemSusChem}, - volume={11}, - number={12}, - pages={1950--1955}, - year={2018}, - publisher={Wiley Online Library} -} - -@article{safari2008multimodal, - title={Multimodal physics-based aging model for life prediction of Li-ion batteries}, - author={Safari, M and Morcrette, Mathieu and Teyssot, A and Delacourt, Charles}, - journal={Journal of The Electrochemical Society}, - volume={156}, - number={3}, - pages={A145}, - year={2008}, - publisher={IOP Publishing} -} - -@article{landesfeind2019temperature, - title={Temperature and concentration dependence of the ionic transport properties of lithium-ion battery electrolytes}, - author={Landesfeind, Johannes and Gasteiger, Hubert A}, - journal={Journal of The Electrochemical Society}, - volume={166}, - number={14}, - pages={A3079--A3097}, - year={2019}, - publisher={The Electrochemical Society} -} -@article{akanni1987effective, - title={Effective transport coefficients in heterogeneous media}, - author={Akanni, KA and Evans, JW and Abramson, IS}, - journal={Chemical Engineering Science}, - volume={42}, - number={8}, - pages={1945--1954}, - year={1987}, - publisher={Elsevier} -} -@article{petersen1958diffusion, - title={Diffusion in a pore of varying cross section}, - author={Petersen, EE}, - journal={AIChE Journal}, - volume={4}, - number={3}, - pages={343--345}, - year={1958}, - publisher={Wiley Online Library} -} -@article{bruggeman1935berechnung, - title={Berechnung verschiedener physikalischer Konstanten von heterogenen Substanzen. I. Dielektrizit{\"a}tskonstanten und Leitf{\"a}higkeiten der Mischk{\"o}rper aus isotropen Substanzen}, - author={Bruggeman, Von DAG}, - journal={Annalen der physik}, - volume={416}, - number={7}, - pages={636--664}, - year={1935}, - publisher={Wiley Online Library} -} -@article{weissberg1963effective, - title={Effective diffusion coefficient in porous media}, - author={Weissberg, Harold L}, - journal={Journal of Applied Physics}, - volume={34}, - number={9}, - pages={2636--2639}, - year={1963}, - publisher={American Institute of Physics} -} -@article{tomadakis1993transport, - title={Transport properties of random arrays of freely overlapping cylinders with various orientation distributions}, - author={Tomadakis, Manolis M and Sotirchos, Stratis V}, - journal={The Journal of chemical physics}, - volume={98}, - number={1}, - pages={616--626}, - year={1993}, - publisher={American Institute of Physics} -} -@article{beeckman1990mathematical, - title={Mathematical description of heterogeneous materials}, - author={Beeckman, JW}, - journal={Chemical engineering science}, - volume={45}, - number={8}, - pages={2603--2610}, - year={1990}, - publisher={Elsevier} -} -@article{mackie1955diffusion, - title={The diffusion of electrolytes in a cation-exchange resin membrane I. Theoretical}, - author={Mackie, JS and Meares, P}, - journal={Proceedings of the Royal Society of London. Series A. Mathematical and Physical Sciences}, - volume={232}, - number={1191}, - pages={498--509}, - year={1955}, - publisher={The Royal Society London} -} -@article{shen2007critical, - title={Critical review of the impact of tortuosity on diffusion}, - author={Shen, Lihua and Chen, Zhangxin}, - journal={Chemical Engineering Science}, - volume={62}, - number={14}, - pages={3748--3755}, - year={2007}, - publisher={Elsevier} -} -@article{Wycisk2022, - title = {Modified Plett-model for modeling voltage hysteresis in lithium-ion cells}, - journal = {Journal of Energy Storage}, - volume = {52}, - pages = {105016}, - year = {2022}, - issn = {2352-152X}, - doi = {https://doi.org/10.1016/j.est.2022.105016}, - url = {https://www.sciencedirect.com/science/article/pii/S2352152X22010192}, - author = {Dominik Wycisk and Marc Oldenburger and Marc Gerry Stoye and Toni Mrkonjic and Arnulf Latz}, - keywords = {Lithium-ion battery, Voltage hysteresis, Plett-model, Silicon–graphite anode}, -} - -@article{Fan2022, - title={Data-driven identification of lithium-ion batteries: A nonlinear equivalent circuit model with diffusion dynamics}, - author={Fan, Chuanxin and O’Regan, Kieran and Li, Liuying and Higgins, Matthew D and Kendrick, Emma and Widanage, Widanalage D}, - journal={Applied Energy}, - volume={321}, - pages={119336}, - year={2022}, - publisher={Elsevier} -} diff --git a/src/pybamm/__init__.py b/src/pybamm/__init__.py index 51c7f49969..f51ba05d02 100644 --- a/src/pybamm/__init__.py +++ b/src/pybamm/__init__.py @@ -75,6 +75,7 @@ from .models.full_battery_models import lead_acid from .models.full_battery_models import lithium_ion from .models.full_battery_models import equivalent_circuit +from .models.full_battery_models import sodium_ion # Submodel classes from .models.submodels.base_submodel import BaseSubModel diff --git a/src/pybamm/input/parameters/__init__.py b/src/pybamm/input/parameters/__init__.py index 9ef23b743d..3c21058270 100644 --- a/src/pybamm/input/parameters/__init__.py +++ b/src/pybamm/input/parameters/__init__.py @@ -1 +1 @@ -__all__ = ['ecm', 'lead_acid', 'lithium_ion'] +__all__ = ['ecm', 'lead_acid', 'lithium_ion', 'sodium_ion'] diff --git a/src/pybamm/input/parameters/lithium_ion/Ai2020.py b/src/pybamm/input/parameters/lithium_ion/Ai2020.py index f578d59fa5..4bf51f3440 100644 --- a/src/pybamm/input/parameters/lithium_ion/Ai2020.py +++ b/src/pybamm/input/parameters/lithium_ion/Ai2020.py @@ -517,11 +517,11 @@ def lico2_ocp_Ai2020(sto): def get_parameter_values(): """ Parameters for the Enertech cell (Ai2020), from the papers :footcite:t:`Ai2019`, - :footcite:t:`rieger2016new` and references therein. + :footcite:t:`Rieger2016` and references therein. SEI parameters are example parameters for SEI growth from the papers - :footcite:t:`Ramadass2004`, :footcite:t:`ploehn2004solvent`, - :footcite:t:`single2018identifying`, :footcite:t:`safari2008multimodal`, and + :footcite:t:`Ramadass2004`, :footcite:t:`Ploehn2004`, + :footcite:t:`Single2018`, :footcite:t:`Safari2008`, and :footcite:t:`Yang2017` .. note:: diff --git a/src/pybamm/input/parameters/lithium_ion/Chen2020.py b/src/pybamm/input/parameters/lithium_ion/Chen2020.py index b3655513a1..eccac74615 100644 --- a/src/pybamm/input/parameters/lithium_ion/Chen2020.py +++ b/src/pybamm/input/parameters/lithium_ion/Chen2020.py @@ -213,8 +213,8 @@ def get_parameter_values(): therein. SEI parameters are example parameters for SEI growth from the papers - :footcite:t:`Ramadass2004`, :footcite:t:`ploehn2004solvent`, - :footcite:t:`single2018identifying`, :footcite:t:`safari2008multimodal`, and + :footcite:t:`Ramadass2004`, :footcite:t:`Ploehn2004`, + :footcite:t:`Single2018`, :footcite:t:`Safari2008`, and :footcite:t:`Yang2017` .. note:: diff --git a/src/pybamm/input/parameters/lithium_ion/Ecker2015.py b/src/pybamm/input/parameters/lithium_ion/Ecker2015.py index 05fbbb2fd7..30ca2ef827 100644 --- a/src/pybamm/input/parameters/lithium_ion/Ecker2015.py +++ b/src/pybamm/input/parameters/lithium_ion/Ecker2015.py @@ -488,8 +488,8 @@ def get_parameter_values(): by Dr. Simon O'Kane in the paper :footcite:t:`Richardson2020` SEI parameters are example parameters for SEI growth from the papers - :footcite:t:`Ramadass2004`, :footcite:t:`ploehn2004solvent`, - :footcite:t:`single2018identifying`, :footcite:t:`safari2008multimodal`, and + :footcite:t:`Ramadass2004`, :footcite:t:`Ploehn2004`, + :footcite:t:`Single2018`, :footcite:t:`Safari2008`, and :footcite:t:`Yang2017` .. note:: diff --git a/src/pybamm/input/parameters/lithium_ion/Marquis2019.py b/src/pybamm/input/parameters/lithium_ion/Marquis2019.py index 16591eac2d..13b8f57966 100644 --- a/src/pybamm/input/parameters/lithium_ion/Marquis2019.py +++ b/src/pybamm/input/parameters/lithium_ion/Marquis2019.py @@ -338,8 +338,8 @@ def get_parameter_values(): and references therein. SEI parameters are example parameters for SEI growth from the papers - :footcite:t:`Ramadass2004`, :footcite:t:`ploehn2004solvent`, - :footcite:t:`single2018identifying`, :footcite:t:`safari2008multimodal`, and + :footcite:t:`Ramadass2004`, :footcite:t:`Ploehn2004`, + :footcite:t:`Single2018`, :footcite:t:`Safari2008`, and :footcite:t:`Yang2017` .. note:: diff --git a/src/pybamm/input/parameters/lithium_ion/Mohtat2020.py b/src/pybamm/input/parameters/lithium_ion/Mohtat2020.py index 0176c3f6a0..044cebe3c5 100644 --- a/src/pybamm/input/parameters/lithium_ion/Mohtat2020.py +++ b/src/pybamm/input/parameters/lithium_ion/Mohtat2020.py @@ -319,8 +319,8 @@ def get_parameter_values(): and references therein. SEI parameters are example parameters for SEI growth from the papers - :footcite:t:`Ramadass2004`, :footcite:t:`ploehn2004solvent`, - :footcite:t:`single2018identifying`, :footcite:t:`safari2008multimodal`, and + :footcite:t:`Ramadass2004`, :footcite:t:`Ploehn2004`, + :footcite:t:`Single2018`, :footcite:t:`Safari2008`, and :footcite:t:`Yang2017` SEI parameters diff --git a/src/pybamm/input/parameters/lithium_ion/NCA_Kim2011.py b/src/pybamm/input/parameters/lithium_ion/NCA_Kim2011.py index 1af610f58a..da1191fa8c 100644 --- a/src/pybamm/input/parameters/lithium_ion/NCA_Kim2011.py +++ b/src/pybamm/input/parameters/lithium_ion/NCA_Kim2011.py @@ -297,8 +297,8 @@ def get_parameter_values(): for the planar effective thermal conductivity. SEI parameters are example parameters for SEI growth from the papers - :footcite:t:`Ramadass2004`, :footcite:t:`ploehn2004solvent`, - :footcite:t:`single2018identifying`, :footcite:t:`safari2008multimodal`, and + :footcite:t:`Ramadass2004`, :footcite:t:`Ploehn2004`, + :footcite:t:`Single2018`, :footcite:t:`Safari2008`, and :footcite:t:`Yang2017` .. note:: diff --git a/src/pybamm/input/parameters/lithium_ion/ORegan2022.py b/src/pybamm/input/parameters/lithium_ion/ORegan2022.py index 45c8cdbcbd..d7e240a7b6 100644 --- a/src/pybamm/input/parameters/lithium_ion/ORegan2022.py +++ b/src/pybamm/input/parameters/lithium_ion/ORegan2022.py @@ -921,7 +921,7 @@ def get_parameter_values(): Parameters for an LG M50 cell, from the paper :footcite:t:`ORegan2022` Parameters for a LiPF6 in EC:EMC (3:7 w:w) electrolyte are from the paper - :footcite:t:`landesfeind2019temperature` and references therein. + :footcite:t:`Landesfeind2019` and references therein. """ return { diff --git a/src/pybamm/input/parameters/lithium_ion/Ramadass2004.py b/src/pybamm/input/parameters/lithium_ion/Ramadass2004.py index a1e24da7e3..82c0df76bf 100644 --- a/src/pybamm/input/parameters/lithium_ion/Ramadass2004.py +++ b/src/pybamm/input/parameters/lithium_ion/Ramadass2004.py @@ -355,7 +355,7 @@ def get_parameter_values(): :footcite:t:`Zhao2018` Parameters for SEI growth are from the papers :footcite:t:`Ramadass2004` and - :footcite:t:`safari2008multimodal` + :footcite:t:`Safari2008` .. note:: Ramadass 2004 has mistakes in units and values of SEI parameters, corrected by diff --git a/src/pybamm/input/parameters/lithium_ion/Xu2019.py b/src/pybamm/input/parameters/lithium_ion/Xu2019.py index caee487339..d1c5edea98 100644 --- a/src/pybamm/input/parameters/lithium_ion/Xu2019.py +++ b/src/pybamm/input/parameters/lithium_ion/Xu2019.py @@ -201,8 +201,8 @@ def get_parameter_values(): ^^^^^^^^^^^^^^^^^^^^^^ SEI parameters are example parameters for SEI growth from the papers - :footcite:t:`Ramadass2004`, :footcite:t:`ploehn2004solvent`, - :footcite:t:`single2018identifying`, :footcite:t:`safari2008multimodal`, and + :footcite:t:`Ramadass2004`, :footcite:t:`Ploehn2004`, + :footcite:t:`Single2018`, :footcite:t:`Safari2008`, and :footcite:t:`Yang2017`. .. note:: diff --git a/src/pybamm/input/parameters/sodium_ion/Chayambuka2022.py b/src/pybamm/input/parameters/sodium_ion/Chayambuka2022.py new file mode 100644 index 0000000000..f8c423cf76 --- /dev/null +++ b/src/pybamm/input/parameters/sodium_ion/Chayambuka2022.py @@ -0,0 +1,341 @@ +import pybamm +import os + +path, _ = os.path.split(os.path.abspath(__file__)) + +U_n_data = pybamm.parameters.process_1D_data("U_n.csv", path=path) +U_p_data = pybamm.parameters.process_1D_data("U_p.csv", path=path) +D_n_data = pybamm.parameters.process_1D_data("D_n.csv", path=path) +D_p_data = pybamm.parameters.process_1D_data("D_p.csv", path=path) +k_n_data = pybamm.parameters.process_1D_data("k_n.csv", path=path) +k_p_data = pybamm.parameters.process_1D_data("k_p.csv", path=path) +D_e_data = pybamm.parameters.process_1D_data("D_e.csv", path=path) +sigma_e_data = pybamm.parameters.process_1D_data("sigma_e.csv", path=path) + + +def HC_ocp_Chayambuka2022(sto): + """ + HC open-circuit potential as a function of stochiometry, data taken + from [1]. + + References + ---------- + .. [1] K. Chayambuka, G. Mulder, D.L. Danilov, P.H.L. Notten, Physics-based + modeling of sodium-ion batteries part II. Model and validation, Electrochimica + Acta 404 (2022) 139764. https://doi.org/10.1016/j.electacta.2021.139764. + + Parameters + ---------- + sto: :class:`pybamm.Symbol` + Electrode stochiometry + + Returns + ------- + :class:`pybamm.Symbol` + Open-circuit potential + """ + + name, (x, y) = U_n_data + return pybamm.Interpolant(x, y, sto, name) + + +def HC_diffusivity_Chayambuka2022(sto, T): + """ + HC diffusivity as a function of stochiometry, the data is taken from [1]. + + References + ---------- + .. [1] K. Chayambuka, G. Mulder, D.L. Danilov, P.H.L. Notten, Physics-based + modeling of sodium-ion batteries part II. Model and validation, Electrochimica + Acta 404 (2022) 139764. https://doi.org/10.1016/j.electacta.2021.139764. + + Parameters + ---------- + sto: :class:`pybamm.Symbol` + Electrode stochiometry + T: :class:`pybamm.Symbol` + Dimensional temperature + + Returns + ------- + :class:`pybamm.Symbol` + Solid diffusivity + """ + + name, (x, y) = D_n_data + c_max = pybamm.Parameter("Maximum concentration in negative electrode [mol.m-3]") + return pybamm.Interpolant(x, y, sto * c_max, name) + + +def HC_electrolyte_exchange_current_density_Chayambuka2022(c_e, c_s_surf, c_s_max, T): + """ + Exchange-current density for Butler-Volmer reactions between HC and NaPF6 in + EC:PC. + + References + ---------- + .. [1] K. Chayambuka, G. Mulder, D.L. Danilov, P.H.L. Notten, Physics-based + modeling of sodium-ion batteries part II. Model and validation, Electrochimica + Acta 404 (2022) 139764. https://doi.org/10.1016/j.electacta.2021.139764. + + Parameters + ---------- + c_e : :class:`pybamm.Symbol` + Electrolyte concentration [mol.m-3] + c_s_surf : :class:`pybamm.Symbol` + Particle concentration [mol.m-3] + c_s_max : :class:`pybamm.Symbol` + Maximum particle concentration [mol.m-3] + T : :class:`pybamm.Symbol` + Temperature [K] + + Returns + ------- + :class:`pybamm.Symbol` + Exchange-current density [A.m-2] + """ + name, (x, y) = k_n_data + k_n = pybamm.Interpolant(x, y, c_s_surf, name) + c_e0 = pybamm.Parameter("Initial concentration in electrolyte [mol.m-3]") + + return ( + pybamm.constants.F + * k_n + * (c_e / c_e0) ** 0.5 + * c_s_surf**0.5 + * (c_s_max - c_s_surf) ** 0.5 + / 2 + ) + + +def NVPF_ocp_Chayambuka2022(sto): + """ + NVPF open-circuit potential as a function of stochiometry, data taken + from [1]. + + References + ---------- + .. [1] K. Chayambuka, G. Mulder, D.L. Danilov, P.H.L. Notten, Physics-based + modeling of sodium-ion batteries part II. Model and validation, Electrochimica + Acta 404 (2022) 139764. https://doi.org/10.1016/j.electacta.2021.139764. + + Parameters + ---------- + sto: :class:`pybamm.Symbol` + Electrode stochiometry + + Returns + ------- + :class:`pybamm.Symbol` + Open-circuit potential + """ + + name, (x, y) = U_p_data + return pybamm.Interpolant(x, y, sto, name) + + +def NVPF_diffusivity_Chayambuka2022(sto, T): + """ + NVPF diffusivity as a function of stochiometry, the data is taken from [1]. + + References + ---------- + .. [1] K. Chayambuka, G. Mulder, D.L. Danilov, P.H.L. Notten, Physics-based + modeling of sodium-ion batteries part II. Model and validation, Electrochimica + Acta 404 (2022) 139764. https://doi.org/10.1016/j.electacta.2021.139764. + + Parameters + ---------- + sto: :class:`pybamm.Symbol` + Electrode stochiometry + T: :class:`pybamm.Symbol` + Dimensional temperature + + Returns + ------- + :class:`pybamm.Symbol` + Solid diffusivity + """ + + name, (x, y) = D_p_data + c_max = pybamm.Parameter("Initial concentration in electrolyte [mol.m-3]") + return pybamm.Interpolant(x, y, sto * c_max, name) + + +def NVPF_electrolyte_exchange_current_density_Chayambuka2022(c_e, c_s_surf, c_s_max, T): + """ + Exchange-current density for Butler-Volmer reactions between NVPF and NaPF6 in + EC:PC. + + References + ---------- + .. [1] K. Chayambuka, G. Mulder, D.L. Danilov, P.H.L. Notten, Physics-based + modeling of sodium-ion batteries part II. Model and validation, Electrochimica + Acta 404 (2022) 139764. https://doi.org/10.1016/j.electacta.2021.139764. + + Parameters + ---------- + c_e : :class:`pybamm.Symbol` + Electrolyte concentration [mol.m-3] + c_s_surf : :class:`pybamm.Symbol` + Particle concentration [mol.m-3] + c_s_max : :class:`pybamm.Symbol` + Maximum particle concentration [mol.m-3] + T : :class:`pybamm.Symbol` + Temperature [K] + + Returns + ------- + :class:`pybamm.Symbol` + Exchange-current density [A.m-2] + """ + name, (x, y) = k_p_data + k_p = pybamm.Interpolant(x, y, c_s_surf, name) + c_e0 = pybamm.Parameter("Initial concentration in electrolyte [mol.m-3]") + + return ( + pybamm.constants.F + * k_p + * (c_e / c_e0) ** 0.5 + * c_s_surf**0.5 + * (c_s_max - c_s_surf) ** 0.5 + / 2 + ) + + +def electrolyte_diffusivity_Chayambuka2022(c_e, T): + """ + Diffusivity of NaPF6 in EC:PC (1:1) as a function of ion concentration. The data + comes from [1] + + References + ---------- + .. [1] K. Chayambuka, G. Mulder, D.L. Danilov, P.H.L. Notten, Physics-based + modeling of sodium-ion batteries part II. Model and validation, Electrochimica + Acta 404 (2022) 139764. https://doi.org/10.1016/j.electacta.2021.139764. + + Parameters + ---------- + c_e: :class:`pybamm.Symbol` + Dimensional electrolyte concentration + T: :class:`pybamm.Symbol` + Dimensional temperature + + Returns + ------- + :class:`pybamm.Symbol` + Solid diffusivity + """ + + name, (x, y) = D_e_data + D_e = pybamm.Interpolant(x, y, c_e, name) + + # Chayambuka et al. (2022) does not provide temperature dependence + + return D_e + + +def electrolyte_conductivity_Chayambuka2022(c_e, T): + """ + Conductivity of NaPF6 in EC:PC (1:1) as a function of ion concentration. The data + comes from [1]. + + References + ---------- + .. [1] K. Chayambuka, G. Mulder, D.L. Danilov, P.H.L. Notten, Physics-based + modeling of sodium-ion batteries part II. Model and validation, Electrochimica + Acta 404 (2022) 139764. https://doi.org/10.1016/j.electacta.2021.139764. + + Parameters + ---------- + c_e: :class:`pybamm.Symbol` + Dimensional electrolyte concentration + T: :class:`pybamm.Symbol` + Dimensional temperature + + Returns + ------- + :class:`pybamm.Symbol` + Solid diffusivity + """ + + name, (x, y) = sigma_e_data + sigma_e = pybamm.Interpolant(x, y, c_e, name) + + # Chayambuka et al. (2022) does not provide temperature dependence + + return sigma_e + + +# Call dict via a function to avoid errors when editing in place +def get_parameter_values(): + """ + Parameters for a sodium-ion cell, from the paper :footcite:t:`Chayambuka2022` and references + therein. The specific parameter values are taken from the COMSOL implementation presented in + [this example](https://www.comsol.com/model/1d-isothermal-sodium-ion-battery-117341). + + """ + + return { + "chemistry": "sodium_ion", + # cell + "Negative electrode thickness [m]": 64e-6, + "Separator thickness [m]": 25e-6, + "Positive electrode thickness [m]": 68e-6, + "Electrode height [m]": 2.54e-4, + "Electrode width [m]": 1, + "Nominal cell capacity [A.h]": 3e-3, + "Current function [A]": 3e-3, + "Contact resistance [Ohm]": 0, + # negative electrode + "Negative electrode conductivity [S.m-1]": 256, + "Maximum concentration in negative electrode [mol.m-3]": 14540, + "Negative particle diffusivity [m2.s-1]": HC_diffusivity_Chayambuka2022, + "Negative electrode OCP [V]": HC_ocp_Chayambuka2022, + "Negative electrode porosity": 0.51, + "Negative electrode active material volume fraction": 0.489, # 1 - 0.51 - 0.001 + "Negative particle radius [m]": 3.48e-6, + "Negative electrode Bruggeman coefficient (electrolyte)": 1.5, + "Negative electrode Bruggeman coefficient (electrode)": 0, + "Negative electrode charge transfer coefficient": 0.5, + "Negative electrode exchange-current density [A.m-2]" + "": HC_electrolyte_exchange_current_density_Chayambuka2022, + "Negative electrode OCP entropic change [V.K-1]": 0, + # positive electrode + "Positive electrode conductivity [S.m-1]": 50, + "Maximum concentration in positive electrode [mol.m-3]": 15320, + "Positive particle diffusivity [m2.s-1]": NVPF_diffusivity_Chayambuka2022, + "Positive electrode OCP [V]": NVPF_ocp_Chayambuka2022, + "Positive electrode porosity": 0.23, + "Positive electrode active material volume fraction": 0.55, # 1 - 0.23 - 0.22 + "Positive particle radius [m]": 0.59e-6, + "Positive electrode Bruggeman coefficient (electrolyte)": 1.5, + "Positive electrode Bruggeman coefficient (electrode)": 0, + "Positive electrode charge transfer coefficient": 0.5, + "Positive electrode exchange-current density [A.m-2]" + "": NVPF_electrolyte_exchange_current_density_Chayambuka2022, + "Positive electrode OCP entropic change [V.K-1]": 0, + # separator + "Separator porosity": 0.55, + "Separator Bruggeman coefficient (electrolyte)": 1.5, + # electrolyte + "Initial concentration in electrolyte [mol.m-3]": 1000, + "Cation transference number": 0.45, + "Thermodynamic factor": 1, + "Electrolyte diffusivity [m2.s-1]": electrolyte_diffusivity_Chayambuka2022, + "Electrolyte conductivity [S.m-1]": electrolyte_conductivity_Chayambuka2022, + # experiment + "Reference temperature [K]": 298.15, + "Ambient temperature [K]": 298.15, + "Number of electrodes connected in parallel to make a cell": 1.0, + "Number of cells connected in series to make a battery": 1.0, + "Lower voltage cut-off [V]": 2.0, + "Upper voltage cut-off [V]": 4.2, + "Open-circuit voltage at 0% SOC [V]": 2.0, + "Open-circuit voltage at 100% SOC [V]": 4.2, + "Initial concentration in negative electrode [mol.m-3]": 13520, + "Initial concentration in positive electrode [mol.m-3]": 3320, + "Initial temperature [K]": 298.15, + # citations + "citations": ["Chayambuka2022"], + } diff --git a/src/pybamm/input/parameters/sodium_ion/__init__.py b/src/pybamm/input/parameters/sodium_ion/__init__.py new file mode 100644 index 0000000000..7591ba5554 --- /dev/null +++ b/src/pybamm/input/parameters/sodium_ion/__init__.py @@ -0,0 +1 @@ +__all__ = ['Chayambuka2022'] diff --git a/src/pybamm/input/parameters/sodium_ion/data/D_e.csv b/src/pybamm/input/parameters/sodium_ion/data/D_e.csv new file mode 100755 index 0000000000..3fe74a8cb8 --- /dev/null +++ b/src/pybamm/input/parameters/sodium_ion/data/D_e.csv @@ -0,0 +1,14 @@ +Electrolyte concentration [mol.m-3],Electrolyte diffusivity [m2.s-1] +1.131153,4.14E-11 +124.121064,3.87E-11 +249.37328,3.62E-11 +387.618465,3.33E-11 +538.734332,3.11E-11 +741.699786,2.81E-11 +1013.696117,2.49E-11 +1272.69948,2.25E-11 +1514.27698,2.14E-11 +1811.953531,1.99E-11 +2113.940691,1.86E-11 +2320.97218,1.79E-11 +2471.904616,1.76E-11 diff --git a/src/pybamm/input/parameters/sodium_ion/data/D_n.csv b/src/pybamm/input/parameters/sodium_ion/data/D_n.csv new file mode 100755 index 0000000000..12d42cce5d --- /dev/null +++ b/src/pybamm/input/parameters/sodium_ion/data/D_n.csv @@ -0,0 +1,40 @@ +Negative particle concentration [mol.m-3],Negative electrode difusivity [m2.s-1] +73.891626,2.57E-16 +246.305419,3.03E-16 +418.719212,3.54E-16 +714.285714,3.99E-16 +1108.374384,4.50E-16 +1477.832512,4.83E-16 +1847.29064,5.31E-16 +2241.37931,6.21E-16 +2733.990148,7.60E-16 +3177.339901,9.20E-16 +3620.689655,1.11E-15 +4113.300493,1.36E-15 +4630.541872,1.57E-15 +5197.044335,1.79E-15 +5714.285714,1.93E-15 +6280.788177,2.02E-15 +6896.551724,1.97E-15 +7413.793103,1.84E-15 +7832.512315,1.67E-15 +8325.123153,1.45E-15 +8669.950739,1.27E-15 +9039.408867,1.06E-15 +9384.236453,8.77E-16 +9729.064039,7.08E-16 +10073.89163,5.44E-16 +10394.08867,4.39E-16 +10714.28571,3.58E-16 +10960.59113,3.14E-16 +11206.89655,2.96E-16 +11502.46305,3.14E-16 +11847.29064,3.80E-16 +12142.85714,4.72E-16 +12487.68473,6.13E-16 +12832.51232,7.78E-16 +13226.60099,1.01E-15 +13719.21182,1.21E-15 +14014.77833,1.28E-15 +14261.08374,1.28E-15 +14433.49754,1.24E-15 diff --git a/src/pybamm/input/parameters/sodium_ion/data/D_p.csv b/src/pybamm/input/parameters/sodium_ion/data/D_p.csv new file mode 100755 index 0000000000..51665bcea9 --- /dev/null +++ b/src/pybamm/input/parameters/sodium_ion/data/D_p.csv @@ -0,0 +1,35 @@ +Positive particle concentration [mol.m-3],Positive electrode difusivity [m2.s-1] +131.578947,2.51E-15 +592.105263,1.71E-15 +1052.631579,1.16E-15 +1535.087719,7.41E-16 +2017.54386,4.61E-16 +2521.929825,2.62E-16 +2982.45614,1.56E-16 +3355.263158,9.92E-17 +3618.421053,7.92E-17 +3925.438596,6.61E-17 +4254.385965,5.65E-17 +4495.614035,5.53E-17 +4890.350877,6.07E-17 +5263.157895,6.65E-17 +5679.824561,7.64E-17 +6096.491228,8.38E-17 +6578.947368,8.79E-17 +7039.473684,8.81E-17 +7587.719298,8.44E-17 +8201.754386,7.52E-17 +8837.719298,6.46E-17 +9495.614035,5.05E-17 +10109.64912,4.13E-17 +10657.89474,3.45E-17 +11184.21053,3.16E-17 +11776.31579,3.17E-17 +12346.49123,3.40E-17 +12828.94737,3.57E-17 +13333.33333,3.66E-17 +13750,3.58E-17 +14254.38596,3.35E-17 +14649.12281,2.74E-17 +15000,2.29E-17 +15197.36842,1.95E-17 diff --git a/src/pybamm/input/parameters/sodium_ion/data/U_n.csv b/src/pybamm/input/parameters/sodium_ion/data/U_n.csv new file mode 100755 index 0000000000..ddb213b3db --- /dev/null +++ b/src/pybamm/input/parameters/sodium_ion/data/U_n.csv @@ -0,0 +1,21 @@ +Negative particle stoichiometry,Negative electrode open-circuit potential [V] +0.001436794,1.318963892 +0.001643334,1.21982507 +0.00811789,1.112038542 +0.01027308,1.077546494 +0.035479844,0.978299913 +0.060758448,0.844570264 +0.090185795,0.719443422 +0.127982471,0.577039126 +0.169900951,0.456168787 +0.232688871,0.317967115 +0.320485995,0.1753473 +0.403954777,0.110332349 +0.483167055,0.088439192 +0.574861484,0.075112923 +0.687380455,0.066007238 +0.799899424,0.056901553 +0.891593855,0.043575284 +0.960353451,0.038968561 +0.987446008,0.034541438 +0.995806356,0.021574368 diff --git a/src/pybamm/input/parameters/sodium_ion/data/U_p.csv b/src/pybamm/input/parameters/sodium_ion/data/U_p.csv new file mode 100755 index 0000000000..a2698567e6 --- /dev/null +++ b/src/pybamm/input/parameters/sodium_ion/data/U_p.csv @@ -0,0 +1,28 @@ +Positive particle stoichiometry,Positive electrode open-circuit potential [V] +0.21,4.288102031 +0.21004478,4.210892773 +0.219269532,4.175283892 +0.261497402,4.172472367 +0.332354842,4.172738781 +0.409317336,4.158176665 +0.474174208,4.152479924 +0.526985168,4.143767596 +0.560316674,4.11121965 +0.575706188,4.048901275 +0.582273973,3.941995276 +0.585975815,3.805375531 +0.590901654,3.725196032 +0.598588947,3.695521965 +0.655863013,3.698707605 +0.696598205,3.69292017 +0.741871138,3.684179499 +0.802205196,3.678465753 +0.864031932,3.675727917 +0.930500897,3.649245158 +0.959279735,3.62262069 +0.979341333,3.530616911 +0.980053837,3.450437411 +0.983058101,3.391026925 +0.992282853,3.355418044 +0.996268304,3.162363722 +0.999940293,3.031684459 diff --git a/src/pybamm/input/parameters/sodium_ion/data/k_n.csv b/src/pybamm/input/parameters/sodium_ion/data/k_n.csv new file mode 100755 index 0000000000..152ebfac4e --- /dev/null +++ b/src/pybamm/input/parameters/sodium_ion/data/k_n.csv @@ -0,0 +1,32 @@ +Negative particle concentration [mol.m-3],Negative electrode exchange-current density rate [m.s-1] +121.359223,3.33E-11 +412.621359,2.15E-11 +631.067961,1.39E-11 +800.970874,9.40E-12 +970.873786,6.88E-12 +1140.776699,5.71E-12 +1262.135922,5.26E-12 +1529.126214,7.03E-12 +1796.116505,1.04E-11 +2063.106796,1.58E-11 +2500,2.65E-11 +3058.252427,4.18E-11 +3713.592233,5.83E-11 +4660.194175,7.48E-11 +5412.621359,7.96E-11 +6067.961165,7.48E-11 +6868.932039,6.47E-11 +7718.446602,4.94E-11 +8422.330097,3.47E-11 +9004.854369,2.39E-11 +9538.834951,1.61E-11 +10024.27184,1.21E-11 +10388.34951,1.06E-11 +10752.42718,1.13E-11 +11213.59223,1.51E-11 +11723.30097,2.25E-11 +12378.64078,3.54E-11 +12912.62136,4.94E-11 +13470.87379,6.34E-11 +14004.85437,7.48E-11 +14417.47573,7.96E-11 diff --git a/src/pybamm/input/parameters/sodium_ion/data/k_p.csv b/src/pybamm/input/parameters/sodium_ion/data/k_p.csv new file mode 100755 index 0000000000..7c228e907c --- /dev/null +++ b/src/pybamm/input/parameters/sodium_ion/data/k_p.csv @@ -0,0 +1,24 @@ +Positive particle concentration [mol.m-3],Positive electrode exchange-current density rate [m.s-1] +21.929825,2.27E-10 +372.807018,1.74E-10 +833.333333,1.24E-10 +1293.859649,8.51E-11 +1907.894737,4.83E-11 +2456.140351,2.96E-11 +2960.526316,1.95E-11 +3442.982456,1.45E-11 +3969.298246,1.16E-11 +4802.631579,1.08E-11 +5548.245614,1.17E-11 +6381.578947,1.18E-11 +7192.982456,1.10E-11 +8092.105263,8.79E-12 +8969.298246,6.65E-12 +9649.122807,5.03E-12 +10350.87719,3.87E-12 +11074.5614,3.34E-12 +12171.05263,3.37E-12 +13223.68421,3.60E-12 +14188.59649,3.30E-12 +14934.21053,2.35E-12 +15328.94737,1.91E-12 diff --git a/src/pybamm/input/parameters/sodium_ion/data/sigma_e.csv b/src/pybamm/input/parameters/sodium_ion/data/sigma_e.csv new file mode 100644 index 0000000000..e8a1104901 --- /dev/null +++ b/src/pybamm/input/parameters/sodium_ion/data/sigma_e.csv @@ -0,0 +1,6 @@ +Electrolyte concentration [mol.m-3],Electrolyte conductivity [S.m-1] +150,0.404 +500,0.72 +1000,0.883 +1500,0.861 +2000,0.76 diff --git a/src/pybamm/models/full_battery_models/__init__.py b/src/pybamm/models/full_battery_models/__init__.py index 135f678289..0260f4dd07 100644 --- a/src/pybamm/models/full_battery_models/__init__.py +++ b/src/pybamm/models/full_battery_models/__init__.py @@ -1,2 +1,2 @@ __all__ = ['base_battery_model', 'equivalent_circuit', 'lead_acid', - 'lithium_ion'] + 'lithium_ion', 'sodium_ion'] diff --git a/src/pybamm/models/full_battery_models/sodium_ion/__init__.py b/src/pybamm/models/full_battery_models/sodium_ion/__init__.py new file mode 100644 index 0000000000..52e4e54952 --- /dev/null +++ b/src/pybamm/models/full_battery_models/sodium_ion/__init__.py @@ -0,0 +1,6 @@ +# +# Root of the sodium-ion models module. +# +from .basic_dfn import BasicDFN + +__all__ = ['basic_dfn'] diff --git a/src/pybamm/models/full_battery_models/sodium_ion/basic_dfn.py b/src/pybamm/models/full_battery_models/sodium_ion/basic_dfn.py new file mode 100644 index 0000000000..c6f618d338 --- /dev/null +++ b/src/pybamm/models/full_battery_models/sodium_ion/basic_dfn.py @@ -0,0 +1,273 @@ +# +# Basic Doyle-Fuller-Newman (DFN) Model +# +import pybamm + + +class BasicDFN(pybamm.lithium_ion.BaseModel): + """Doyle-Fuller-Newman (DFN) model of a sodium-ion battery, from + :footcite:t:`Marquis2019`. + + Parameters + ---------- + name : str, optional + The name of the model. + + """ + + def __init__(self, name="Doyle-Fuller-Newman model"): + super().__init__(name=name) + pybamm.citations.register("Marquis2019") + # `param` is a class containing all the relevant parameters and functions for + # this model. These are purely symbolic at this stage, and will be set by the + # `ParameterValues` class when the model is processed. + param = self.param + + ###################### + # Variables + ###################### + # Variables that depend on time only are created without a domain + Q = pybamm.Variable("Discharge capacity [A.h]") + + # Variables that vary spatially are created with a domain + c_e_n = pybamm.Variable( + "Negative electrolyte concentration [mol.m-3]", + domain="negative electrode", + ) + c_e_s = pybamm.Variable( + "Separator electrolyte concentration [mol.m-3]", + domain="separator", + ) + c_e_p = pybamm.Variable( + "Positive electrolyte concentration [mol.m-3]", + domain="positive electrode", + ) + # Concatenations combine several variables into a single variable, to simplify + # implementing equations that hold over several domains + c_e = pybamm.concatenation(c_e_n, c_e_s, c_e_p) + + # Electrolyte potential + phi_e_n = pybamm.Variable( + "Negative electrolyte potential [V]", + domain="negative electrode", + ) + phi_e_s = pybamm.Variable( + "Separator electrolyte potential [V]", + domain="separator", + ) + phi_e_p = pybamm.Variable( + "Positive electrolyte potential [V]", + domain="positive electrode", + ) + phi_e = pybamm.concatenation(phi_e_n, phi_e_s, phi_e_p) + + # Electrode potential + phi_s_n = pybamm.Variable( + "Negative electrode potential [V]", domain="negative electrode" + ) + phi_s_p = pybamm.Variable( + "Positive electrode potential [V]", + domain="positive electrode", + ) + # Particle concentrations are variables on the particle domain, but also vary in + # the x-direction (electrode domain) and so must be provided with auxiliary + # domains + c_s_n = pybamm.Variable( + "Negative particle concentration [mol.m-3]", + domain="negative particle", + auxiliary_domains={"secondary": "negative electrode"}, + ) + c_s_p = pybamm.Variable( + "Positive particle concentration [mol.m-3]", + domain="positive particle", + auxiliary_domains={"secondary": "positive electrode"}, + ) + + # Constant temperature + T = param.T_init + + ###################### + # Other set-up + ###################### + + # Current density + i_cell = param.current_density_with_time + + # Porosity + # Primary broadcasts are used to broadcast scalar quantities across a domain + # into a vector of the right shape, for multiplying with other vectors + eps_n = pybamm.PrimaryBroadcast( + pybamm.Parameter("Negative electrode porosity"), "negative electrode" + ) + eps_s = pybamm.PrimaryBroadcast( + pybamm.Parameter("Separator porosity"), "separator" + ) + eps_p = pybamm.PrimaryBroadcast( + pybamm.Parameter("Positive electrode porosity"), "positive electrode" + ) + eps = pybamm.concatenation(eps_n, eps_s, eps_p) + + # Active material volume fraction (eps + eps_s + eps_inactive = 1) + eps_s_n = pybamm.Parameter("Negative electrode active material volume fraction") + eps_s_p = pybamm.Parameter("Positive electrode active material volume fraction") + + # transport_efficiency + tor = pybamm.concatenation( + eps_n**param.n.b_e, eps_s**param.s.b_e, eps_p**param.p.b_e + ) + a_n = 3 * param.n.prim.epsilon_s_av / param.n.prim.R_typ + a_p = 3 * param.p.prim.epsilon_s_av / param.p.prim.R_typ + + # Interfacial reactions + # Surf takes the surface value of a variable, i.e. its boundary value on the + # right side. This is also accessible via `boundary_value(x, "right")`, with + # "left" providing the boundary value of the left side + c_s_surf_n = pybamm.surf(c_s_n) + sto_surf_n = c_s_surf_n / param.n.prim.c_max + j0_n = param.n.prim.j0(c_e_n, c_s_surf_n, T) + eta_n = phi_s_n - phi_e_n - param.n.prim.U(sto_surf_n, T) + Feta_RT_n = param.F * eta_n / (param.R * T) + j_n = 2 * j0_n * pybamm.sinh(param.n.prim.ne / 2 * Feta_RT_n) + + c_s_surf_p = pybamm.surf(c_s_p) + sto_surf_p = c_s_surf_p / param.p.prim.c_max + j0_p = param.p.prim.j0(c_e_p, c_s_surf_p, T) + eta_p = phi_s_p - phi_e_p - param.p.prim.U(sto_surf_p, T) + Feta_RT_p = param.F * eta_p / (param.R * T) + j_s = pybamm.PrimaryBroadcast(0, "separator") + j_p = 2 * j0_p * pybamm.sinh(param.p.prim.ne / 2 * Feta_RT_p) + + a_j_n = a_n * j_n + a_j_p = a_p * j_p + a_j = pybamm.concatenation(a_j_n, j_s, a_j_p) + + ###################### + # State of Charge + ###################### + I = param.current_with_time + # The `rhs` dictionary contains differential equations, with the key being the + # variable in the d/dt + self.rhs[Q] = I / 3600 + # Initial conditions must be provided for the ODEs + self.initial_conditions[Q] = pybamm.Scalar(0) + + ###################### + # Particles + ###################### + + # The div and grad operators will be converted to the appropriate matrix + # multiplication at the discretisation stage + N_s_n = -param.n.prim.D(c_s_n, T) * pybamm.grad(c_s_n) + N_s_p = -param.p.prim.D(c_s_p, T) * pybamm.grad(c_s_p) + self.rhs[c_s_n] = -pybamm.div(N_s_n) + self.rhs[c_s_p] = -pybamm.div(N_s_p) + # Boundary conditions must be provided for equations with spatial derivatives + self.boundary_conditions[c_s_n] = { + "left": (pybamm.Scalar(0), "Neumann"), + "right": ( + -j_n / (param.F * pybamm.surf(param.n.prim.D(c_s_n, T))), + "Neumann", + ), + } + self.boundary_conditions[c_s_p] = { + "left": (pybamm.Scalar(0), "Neumann"), + "right": ( + -j_p / (param.F * pybamm.surf(param.p.prim.D(c_s_p, T))), + "Neumann", + ), + } + self.initial_conditions[c_s_n] = param.n.prim.c_init + self.initial_conditions[c_s_p] = param.p.prim.c_init + ###################### + # Current in the solid + ###################### + sigma_eff_n = param.n.sigma(T) * eps_s_n**param.n.b_s + i_s_n = -sigma_eff_n * pybamm.grad(phi_s_n) + sigma_eff_p = param.p.sigma(T) * eps_s_p**param.p.b_s + i_s_p = -sigma_eff_p * pybamm.grad(phi_s_p) + # The `algebraic` dictionary contains differential equations, with the key being + # the main scalar variable of interest in the equation + # multiply by Lx**2 to improve conditioning + self.algebraic[phi_s_n] = param.L_x**2 * (pybamm.div(i_s_n) + a_j_n) + self.algebraic[phi_s_p] = param.L_x**2 * (pybamm.div(i_s_p) + a_j_p) + self.boundary_conditions[phi_s_n] = { + "left": (pybamm.Scalar(0), "Dirichlet"), + "right": (pybamm.Scalar(0), "Neumann"), + } + self.boundary_conditions[phi_s_p] = { + "left": (pybamm.Scalar(0), "Neumann"), + "right": (i_cell / pybamm.boundary_value(-sigma_eff_p, "right"), "Neumann"), + } + # Initial conditions must also be provided for algebraic equations, as an + # initial guess for a root-finding algorithm which calculates consistent initial + # conditions + self.initial_conditions[phi_s_n] = pybamm.Scalar(0) + self.initial_conditions[phi_s_p] = param.ocv_init + + ###################### + # Current in the electrolyte + ###################### + i_e = (param.kappa_e(c_e, T) * tor) * ( + param.chiRT_over_Fc(c_e, T) * pybamm.grad(c_e) - pybamm.grad(phi_e) + ) + # multiply by Lx**2 to improve conditioning + self.algebraic[phi_e] = param.L_x**2 * (pybamm.div(i_e) - a_j) + self.boundary_conditions[phi_e] = { + "left": (pybamm.Scalar(0), "Neumann"), + "right": (pybamm.Scalar(0), "Neumann"), + } + self.initial_conditions[phi_e] = -param.n.prim.U_init + + ###################### + # Electrolyte concentration + ###################### + N_e = -tor * param.D_e(c_e, T) * pybamm.grad(c_e) + self.rhs[c_e] = (1 / eps) * ( + -pybamm.div(N_e) + (1 - param.t_plus(c_e, T)) * a_j / param.F + ) + self.boundary_conditions[c_e] = { + "left": (pybamm.Scalar(0), "Neumann"), + "right": (pybamm.Scalar(0), "Neumann"), + } + self.initial_conditions[c_e] = param.c_e_init + + ###################### + # (Some) variables + ###################### + voltage = pybamm.boundary_value(phi_s_p, "right") + num_cells = pybamm.Parameter( + "Number of cells connected in series to make a battery" + ) + # The `variables` dictionary contains all variables that might be useful for + # visualising the solution of the model + self.variables = { + "Negative particle concentration [mol.m-3]": c_s_n, + "Negative particle surface concentration [mol.m-3]": c_s_surf_n, + "Electrolyte concentration [mol.m-3]": c_e, + "Negative electrolyte concentration [mol.m-3]": c_e_n, + "Separator electrolyte concentration [mol.m-3]": c_e_s, + "Positive electrolyte concentration [mol.m-3]": c_e_p, + "Positive particle concentration [mol.m-3]": c_s_p, + "Positive particle surface concentration [mol.m-3]": c_s_surf_p, + "Current [A]": I, + "Current variable [A]": I, # for compatibility with pybamm.Experiment + "Negative electrode potential [V]": phi_s_n, + "Electrolyte potential [V]": phi_e, + "Negative electrolyte potential [V]": phi_e_n, + "Separator electrolyte potential [V]": phi_e_s, + "Positive electrolyte potential [V]": phi_e_p, + "Positive electrode potential [V]": phi_s_p, + "Voltage [V]": voltage, + "Battery voltage [V]": voltage * num_cells, + "Time [s]": pybamm.t, + "Discharge capacity [A.h]": Q, + } + # Events specify points at which a solution should terminate + self.events += [ + pybamm.Event("Minimum voltage [V]", voltage - param.voltage_low_cut), + pybamm.Event("Maximum voltage [V]", param.voltage_high_cut - voltage), + ] + + @property + def default_parameter_values(self): + return pybamm.ParameterValues("Chayambuka2022") diff --git a/src/pybamm/models/submodels/thermal/surface/lumped.py b/src/pybamm/models/submodels/thermal/surface/lumped.py index dc481947e8..9fe3118e2f 100644 --- a/src/pybamm/models/submodels/thermal/surface/lumped.py +++ b/src/pybamm/models/submodels/thermal/surface/lumped.py @@ -19,7 +19,7 @@ class Lumped(pybamm.BaseSubModel): def __init__(self, param, options=None): super().__init__(param, options=options) - pybamm.citations.register("lin2014lumped") + pybamm.citations.register("Lin2014") def get_fundamental_variables(self): T_surf = pybamm.Variable("Surface temperature [K]") diff --git a/src/pybamm/models/submodels/transport_efficiency/bruggeman.py b/src/pybamm/models/submodels/transport_efficiency/bruggeman.py index ec26d7955d..a960f20e66 100644 --- a/src/pybamm/models/submodels/transport_efficiency/bruggeman.py +++ b/src/pybamm/models/submodels/transport_efficiency/bruggeman.py @@ -7,7 +7,7 @@ class Bruggeman(BaseModel): """Submodel for Bruggeman transport_efficiency, - :footcite:t:`bruggeman1935berechnung` + :footcite:t:`Bruggeman1935` Parameters ---------- @@ -28,7 +28,7 @@ def get_coupled_variables(self, variables): for domain in self.options.whole_cell_domains: Domain = domain.capitalize() eps_k = variables[f"{Domain} porosity"] - pybamm.citations.register("bruggeman1935berechnung") + pybamm.citations.register("Bruggeman1935") b_k = self.param.domain_params[domain.split()[0]].b_e tor_k = eps_k**b_k tor_dict[domain] = tor_k @@ -40,7 +40,7 @@ def get_coupled_variables(self, variables): else: Domain = domain.capitalize() phi_k = 1 - variables[f"{Domain} porosity"] - pybamm.citations.register("bruggeman1935berechnung") + pybamm.citations.register("Bruggeman1935") b_k = self.param.domain_params[domain.split()[0]].b_s tor_k = phi_k**b_k tor_dict[domain] = tor_k diff --git a/src/pybamm/models/submodels/transport_efficiency/cation_exchange_membrane.py b/src/pybamm/models/submodels/transport_efficiency/cation_exchange_membrane.py index 3ffb57e7de..b9165cf255 100644 --- a/src/pybamm/models/submodels/transport_efficiency/cation_exchange_membrane.py +++ b/src/pybamm/models/submodels/transport_efficiency/cation_exchange_membrane.py @@ -7,7 +7,7 @@ class CationExchangeMembrane(BaseModel): """Submodel for Cation Exchange Membrane transport_efficiency, - :footcite:t:`bruggeman1935berechnung`, :footcite:t:`shen2007critical` + :footcite:t:`Bruggeman1935`, :footcite:t:`Shen2007` Parameters ---------- @@ -23,8 +23,8 @@ def __init__(self, param, component, options=None): super().__init__(param, component, options=options) def get_coupled_variables(self, variables): - pybamm.citations.register("shen2007critical") - pybamm.citations.register("mackie1955diffusion") + pybamm.citations.register("Shen2007") + pybamm.citations.register("Mackie1955") if self.component == "Electrolyte": tor_dict = {} for domain in self.options.whole_cell_domains: diff --git a/src/pybamm/models/submodels/transport_efficiency/heterogeneous_catalyst.py b/src/pybamm/models/submodels/transport_efficiency/heterogeneous_catalyst.py index 7ec8bc3580..f60f71765c 100644 --- a/src/pybamm/models/submodels/transport_efficiency/heterogeneous_catalyst.py +++ b/src/pybamm/models/submodels/transport_efficiency/heterogeneous_catalyst.py @@ -7,7 +7,7 @@ class HeterogeneousCatalyst(BaseModel): """Submodel for Heterogeneous Catalyst transport_efficiency - :footcite:t:`beeckman1990mathematical`, :footcite:t:`shen2007critical` + :footcite:t:`Beeckman1990`, :footcite:t:`Shen2007` Parameters ---------- @@ -23,8 +23,8 @@ def __init__(self, param, component, options=None): super().__init__(param, component, options=options) def get_coupled_variables(self, variables): - pybamm.citations.register("shen2007critical") - pybamm.citations.register("beeckman1990mathematical") + pybamm.citations.register("Shen2007") + pybamm.citations.register("Beeckman1990") if self.component == "Electrolyte": tor_dict = {} for domain in self.options.whole_cell_domains: diff --git a/src/pybamm/models/submodels/transport_efficiency/hyperbola_of_revolution.py b/src/pybamm/models/submodels/transport_efficiency/hyperbola_of_revolution.py index 306c66b774..fe7e8dfb1d 100644 --- a/src/pybamm/models/submodels/transport_efficiency/hyperbola_of_revolution.py +++ b/src/pybamm/models/submodels/transport_efficiency/hyperbola_of_revolution.py @@ -7,7 +7,7 @@ class HyperbolaOfRevolution(BaseModel): """Submodel for Hyperbola of revolution transport_efficiency - :footcite:t:`petersen1958diffusion`, :footcite:t:`shen2007critical` + :footcite:t:`Petersen1958`, :footcite:t:`Shen2007` Parameters ---------- @@ -23,8 +23,8 @@ def __init__(self, param, component, options=None): super().__init__(param, component, options=options) def get_coupled_variables(self, variables): - pybamm.citations.register("shen2007critical") - pybamm.citations.register("petersen1958diffusion") + pybamm.citations.register("Shen2007") + pybamm.citations.register("Petersen1958") if self.component == "Electrolyte": tor_dict = {} for domain in self.options.whole_cell_domains: diff --git a/src/pybamm/models/submodels/transport_efficiency/ordered_packing.py b/src/pybamm/models/submodels/transport_efficiency/ordered_packing.py index 13b3a3515e..4b9e9b5dc5 100644 --- a/src/pybamm/models/submodels/transport_efficiency/ordered_packing.py +++ b/src/pybamm/models/submodels/transport_efficiency/ordered_packing.py @@ -7,7 +7,7 @@ class OrderedPacking(BaseModel): """Submodel for Ordered Packing transport_efficiency - :footcite:t:`akanni1987effective`, :footcite:t:`shen2007critical` + :footcite:t:`Akanni1987`, :footcite:t:`Shen2007` Parameters ---------- @@ -23,8 +23,8 @@ def __init__(self, param, component, options=None): super().__init__(param, component, options=options) def get_coupled_variables(self, variables): - pybamm.citations.register("shen2007critical") - pybamm.citations.register("akanni1987effective") + pybamm.citations.register("Shen2007") + pybamm.citations.register("Akanni1987") if self.component == "Electrolyte": tor_dict = {} for domain in self.options.whole_cell_domains: diff --git a/src/pybamm/models/submodels/transport_efficiency/overlapping_spheres.py b/src/pybamm/models/submodels/transport_efficiency/overlapping_spheres.py index 9bbed1fd05..ae2dbc590d 100644 --- a/src/pybamm/models/submodels/transport_efficiency/overlapping_spheres.py +++ b/src/pybamm/models/submodels/transport_efficiency/overlapping_spheres.py @@ -7,7 +7,7 @@ class OverlappingSpheres(BaseModel): """Submodel for Overlapping Spheres transport_efficiency - :footcite:t:`weissberg1963effective`, :footcite:t:`shen2007critical` + :footcite:t:`Weissberg1963`, :footcite:t:`Shen2007` Parameters ---------- @@ -23,8 +23,8 @@ def __init__(self, param, component, options=None): super().__init__(param, component, options=options) def get_coupled_variables(self, variables): - pybamm.citations.register("shen2007critical") - pybamm.citations.register("weissberg1963effective") + pybamm.citations.register("Shen2007") + pybamm.citations.register("Weissberg1963") if self.component == "Electrolyte": tor_dict = {} for domain in self.options.whole_cell_domains: diff --git a/src/pybamm/models/submodels/transport_efficiency/random_overlapping_cylinders.py b/src/pybamm/models/submodels/transport_efficiency/random_overlapping_cylinders.py index da32f2f4fe..b9eb49a54e 100644 --- a/src/pybamm/models/submodels/transport_efficiency/random_overlapping_cylinders.py +++ b/src/pybamm/models/submodels/transport_efficiency/random_overlapping_cylinders.py @@ -7,7 +7,7 @@ class RandomOverlappingCylinders(BaseModel): """Submodel for Random Overlapping Cylinders transport_efficiency, - :footcite:t:`tomadakis1993transport`, :footcite:t:`shen2007critical` + :footcite:t:`Tomadakis1993`, :footcite:t:`Shen2007` Parameters ---------- @@ -23,8 +23,8 @@ def __init__(self, param, component, options=None): super().__init__(param, component, options=options) def get_coupled_variables(self, variables): - pybamm.citations.register("shen2007critical") - pybamm.citations.register("tomadakis1993transport") + pybamm.citations.register("Shen2007") + pybamm.citations.register("Tomadakis1993") if self.component == "Electrolyte": tor_dict = {} for domain in self.options.whole_cell_domains: diff --git a/src/pybamm/parameters/parameter_sets.py b/src/pybamm/parameters/parameter_sets.py index a3ddd0ed2e..22b476f4e0 100644 --- a/src/pybamm/parameters/parameter_sets.py +++ b/src/pybamm/parameters/parameter_sets.py @@ -18,7 +18,7 @@ class ParameterSets(Mapping): >>> import pybamm >>> list(pybamm.parameter_sets) - ['Ai2020', 'Chen2020', ...] + ['Ai2020', 'Chayambuka2022', ...] Get the docstring for a parameter set: @@ -26,7 +26,7 @@ class ParameterSets(Mapping): >>> print(pybamm.parameter_sets.get_docstring("Ai2020")) Parameters for the Enertech cell (Ai2020), from the papers :footcite:t:`Ai2019`, - :footcite:t:`rieger2016new` and references therein. + :footcite:t:`Rieger2016` and references therein. ... See also: :ref:`adding-parameter-sets` diff --git a/src/pybamm/solvers/jax_bdf_solver.py b/src/pybamm/solvers/jax_bdf_solver.py index 3db82ca0da..a07ad8505b 100644 --- a/src/pybamm/solvers/jax_bdf_solver.py +++ b/src/pybamm/solvers/jax_bdf_solver.py @@ -68,7 +68,7 @@ def caller(*args): def _bdf_odeint(fun, mass, rtol, atol, y0, t_eval, *args): """ Implements a Backward Difference formula (BDF) implicit multistep integrator. - The basic algorithm is derived in :footcite:t:`byrne1975polyalgorithm`. This + The basic algorithm is derived in :footcite:t:`Byrne1975`. This particular implementation follows that implemented in the Matlab routine ode15s described in :footcite:t:`shamphine1997matlab` and the SciPy implementation :footcite:t:`Virtanen2020`, which features the NDF formulas for improved @@ -362,7 +362,7 @@ def _select_initial_step(atol, rtol, fun, t0, y0, f0, h0): comparing the predicted state against that using the provided function. Optimal step size based on the selected order is obtained using formula (4.12) - in :footcite:t:`hairer1993solving`. + in :footcite:t:`Hairer1993`. """ scale = atol + jnp.abs(y0) * rtol @@ -926,14 +926,14 @@ def ravel_first_arg_(unravel, y_flat, *args): def jax_bdf_integrate(func, y0, t_eval, *args, rtol=1e-6, atol=1e-6, mass=None): """ Backward Difference formula (BDF) implicit multistep integrator. The basic algorithm - is derived in :footcite:t:`byrne1975polyalgorithm`. This particular implementation - follows the Matlab routine ode15s described in :footcite:t:`shampine1997matlab` - and the SciPy implementation :footcite:t:`Virtanen2020` which features - the NDF formulas for improved stability, with associated differences in the - error constants, and calculates the jacobian at J(t_{n+1}, y^0_{n+1}). This - implementation was based on that implemented in the SciPy library - :footcite:t:`Virtanen2020`, which also mainly follows :footcite:t:`shampine1997matlab` - but uses the more standard jacobian update. + is derived in :footcite:t:`Byrne1975`. This particular implementation + follows that implemented in the Matlab routine ode15s described in + :footcite:t:`Shampine1997` and the SciPy implementation + :footcite:t:`Virtanen2020` which features the NDF formulas for improved stability, + with associated differences in the error constants, and calculates the jacobian at + J(t_{n+1}, y^0_{n+1}). This implementation was based on that implemented in the + SciPy library :footcite:t:`Virtanen2020`, which also mainly follows + :footcite:t:`Shampine1997` but uses the more standard jacobian update. Parameters ---------- diff --git a/src/pybamm/spatial_methods/spectral_volume.py b/src/pybamm/spatial_methods/spectral_volume.py index 11c6dfd6d2..8699045dca 100644 --- a/src/pybamm/spatial_methods/spectral_volume.py +++ b/src/pybamm/spatial_methods/spectral_volume.py @@ -176,7 +176,7 @@ def cv_boundary_reconstruction_matrix(self, domains): def chebyshev_differentiation_matrices(self, noe, dod): """ Chebyshev differentiation matrices, from - :footcite:t:`baltensperger2003spectral`. + :footcite:t:`Baltensperger2003`. Parameters ---------- diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_basic_models.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_basic_models.py index abb0169d06..3288db75fe 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_basic_models.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_basic_models.py @@ -16,7 +16,16 @@ def test_with_experiment(self): ] ) sim = pybamm.Simulation(model, experiment=experiment) - sim.solve(calc_esoh=False) + sol = sim.solve(calc_esoh=False) + + # Check the solve returned a solution + assert sol is not None + + # Check that the solution contains the expected number of cycles + assert len(sol.cycles) == 3 + + # Check that the solution terminated because it reached final time + assert sol.termination == "final time" class TestBasicSPM(BaseBasicModelTest): diff --git a/tests/integration/test_models/test_full_battery_models/test_sodium_ion/__init__.py b/tests/integration/test_models/test_full_battery_models/test_sodium_ion/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/integration/test_models/test_full_battery_models/test_sodium_ion/test_basic_models.py b/tests/integration/test_models/test_full_battery_models/test_sodium_ion/test_basic_models.py new file mode 100644 index 0000000000..2e0321cb1b --- /dev/null +++ b/tests/integration/test_models/test_full_battery_models/test_sodium_ion/test_basic_models.py @@ -0,0 +1,34 @@ +# +# Test basic model classes +# +import pybamm +import pytest + + +class BaseBasicModelTest: + def test_with_experiment(self): + model = self.model + experiment = pybamm.Experiment( + [ + "Discharge at C/3 until 3.5V", + "Hold at 3.5V for 1 hour", + "Rest for 10 min", + ] + ) + sim = pybamm.Simulation(model, experiment=experiment) + sol = sim.solve(calc_esoh=False) + + # Check the solve returned a solution + assert sol is not None + + # Check that the solution contains the expected number of cycles + assert len(sol.cycles) == 3 + + # Check that the solution terminated because it reached final time + assert sol.termination == "final time" + + +class TestBasicDFN(BaseBasicModelTest): + @pytest.fixture(autouse=True) + def setup(self): + self.model = pybamm.sodium_ion.BasicDFN() diff --git a/tests/unit/test_models/test_full_battery_models/test_sodium_ion/__init__.py b/tests/unit/test_models/test_full_battery_models/test_sodium_ion/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/unit/test_models/test_full_battery_models/test_sodium_ion/test_basic_models.py b/tests/unit/test_models/test_full_battery_models/test_sodium_ion/test_basic_models.py new file mode 100644 index 0000000000..6b085d3a79 --- /dev/null +++ b/tests/unit/test_models/test_full_battery_models/test_sodium_ion/test_basic_models.py @@ -0,0 +1,14 @@ +# +# Tests for the basic sodium-ion models +# +import pybamm + + +class TestBasicModels: + def test_dfn_well_posed(self): + model = pybamm.sodium_ion.BasicDFN() + model.check_well_posedness() + + def test_default_parameters(self): + model = pybamm.sodium_ion.BasicDFN() + assert "Chayambuka2022" in model.default_parameter_values["citations"] diff --git a/tests/unit/test_parameters/test_parameter_sets/test_Chayambuka2022.py b/tests/unit/test_parameters/test_parameter_sets/test_Chayambuka2022.py new file mode 100644 index 0000000000..db2eea0d65 --- /dev/null +++ b/tests/unit/test_parameters/test_parameter_sets/test_Chayambuka2022.py @@ -0,0 +1,41 @@ +# +# Tests for Chayambuka et al (2022) parameter set +# + +import pytest +import pybamm + + +class TestChayambuka2022: + def test_functions(self): + param = pybamm.ParameterValues("Chayambuka2022") + sto = pybamm.Scalar(0.5) + T = pybamm.Scalar(298.15) + c_e = 1000 + c_n_max = 14540 + c_p_max = 15320 + + fun_test = { + # Negative electrode + "Negative particle diffusivity [m2.s-1]": ([sto, T], 1.8761e-15), + "Negative electrode OCP [V]": ([sto], 0.0859), + "Negative electrode exchange-current density [A.m-2]" "": ( + [c_e, sto * c_n_max, c_n_max, T], + 0.0202, + ), + # Positive electrode + "Positive particle diffusivity [m2.s-1]": ([sto, T], 1.8700e-15), + "Positive electrode OCP [V]": ([sto], 4.1482), + "Positive electrode exchange-current density [A.m-2]" "": ( + [c_e, sto * c_p_max, c_p_max, T], + 0.0036, + ), + # Electrolyte + "Electrolyte diffusivity [m2.s-1]": ([c_e, T], 2.5061e-10), + "Electrolyte conductivity [S.m-1]": ([c_e, T], 0.8830), + } + + for name, value in fun_test.items(): + assert param.evaluate(param[name](*value[0])) == pytest.approx( + value[1], abs=0.0001 + )