diff --git a/.all-contributorsrc b/.all-contributorsrc
index 4366246007..dcde101e80 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -747,7 +747,8 @@
"profile": "https://github.com/AbhishekChaudharii",
"contributions": [
"doc",
- "code"
+ "code",
+ "test"
]
},
{
@@ -960,6 +961,36 @@
"code",
"test"
]
+ },
+ {
+ "login": "medha-14",
+ "name": "Medha Bhardwaj",
+ "avatar_url": "https://avatars.githubusercontent.com/u/143182673?v=4",
+ "profile": "https://github.com/medha-14",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "MarcBerliner",
+ "name": "Marc Berliner",
+ "avatar_url": "https://avatars.githubusercontent.com/u/34451391?v=4",
+ "profile": "http://marcberliner.com",
+ "contributions": [
+ "code",
+ "doc",
+ "infra",
+ "maintenance"
+ ]
+ },
+ {
+ "login": "Aswinr24",
+ "name": "Aswinr24",
+ "avatar_url": "https://avatars.githubusercontent.com/u/135364633?v=4",
+ "profile": "https://github.com/Aswinr24",
+ "contributions": [
+ "test"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 0f503f09a7..6984abf32c 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -10,7 +10,7 @@ src/pybamm/meshes/ @martinjrobins @rtimms @valentinsulzer @rtimms
src/pybamm/models/ @brosaplanella @DrSOKane @rtimms @valentinsulzer @TomTranter @rtimms
src/pybamm/parameters/ @brosaplanella @DrSOKane @rtimms @valentinsulzer @TomTranter @rtimms @kratman
src/pybamm/plotting/ @martinjrobins @rtimms @Saransh-cpp @valentinsulzer @rtimms @kratman @agriyakhetarpal
-src/pybamm/solvers/ @martinjrobins @rtimms @valentinsulzer @TomTranter @rtimms
+src/pybamm/solvers/ @martinjrobins @rtimms @valentinsulzer @TomTranter @rtimms @MarcBerliner
src/pybamm/spatial_methods/ @martinjrobins @rtimms @valentinsulzer @rtimms
src/pybamm/* @pybamm-team/maintainers # the files directly under /pybamm/, will not recurse
diff --git a/.github/release_reminder.md b/.github/release_reminder.md
deleted file mode 100644
index 09c524fbec..0000000000
--- a/.github/release_reminder.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-title: Create {{ date | date('YY.MM') }} (final or rc0) release
-labels: "priority: high"
----
-Quarterly reminder to create a -
-
-1. pre-release if the month has just started.
-2. non-pre-release if the month is about to end (**before the end of the month**).
-
-See [Release Workflow](https://github.com/pybamm-team/PyBaMM/blob/develop/.github/release_workflow.md) for more information.
diff --git a/.github/workflows/benchmark_on_push.yml b/.github/workflows/benchmark_on_push.yml
index 2883eb5f26..3aa9fce9c0 100644
--- a/.github/workflows/benchmark_on_push.yml
+++ b/.github/workflows/benchmark_on_push.yml
@@ -8,6 +8,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
+env:
+ PYBAMM_DISABLE_TELEMETRY: "true"
+
jobs:
benchmarks:
runs-on: ubuntu-latest
diff --git a/.github/workflows/lychee_url_checker.yml b/.github/workflows/lychee_url_checker.yml
index 9a636fda8a..e595bff826 100644
--- a/.github/workflows/lychee_url_checker.yml
+++ b/.github/workflows/lychee_url_checker.yml
@@ -28,7 +28,7 @@ jobs:
# use stable version for now to avoid breaking changes
- name: Lychee URL checker
- uses: lycheeverse/lychee-action@v1.10.0
+ uses: lycheeverse/lychee-action@v2.1.0
with:
# arguments with file types to check
args: >-
diff --git a/.github/workflows/periodic_benchmarks.yml b/.github/workflows/periodic_benchmarks.yml
index 641627c0ba..30603a0ea9 100644
--- a/.github/workflows/periodic_benchmarks.yml
+++ b/.github/workflows/periodic_benchmarks.yml
@@ -15,6 +15,9 @@ on:
# workflow manually
workflow_dispatch:
+env:
+ PYBAMM_DISABLE_TELEMETRY: "true"
+
jobs:
benchmarks:
runs-on: ubuntu-latest
@@ -51,7 +54,7 @@ jobs:
LD_LIBRARY_PATH: $HOME/.local/lib
- name: Upload results as artifact
- uses: actions/upload-artifact@v4.3.6
+ uses: actions/upload-artifact@v4.4.3
with:
name: asv_periodic_results
path: results
diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml
index 9ca277b653..944c900e9a 100644
--- a/.github/workflows/publish_pypi.yml
+++ b/.github/workflows/publish_pypi.yml
@@ -18,6 +18,7 @@ on:
# Set options available for all jobs that use cibuildwheel
env:
+ PYBAMM_DISABLE_TELEMETRY: "true"
# Increase pip debugging output, equivalent to `pip -vv`
CIBW_BUILD_VERBOSITY: 2
# Disable build isolation to allow pre-installing build-time dependencies.
@@ -75,6 +76,7 @@ jobs:
run: pipx run cibuildwheel --output-dir wheelhouse
env:
CIBW_ENVIRONMENT: >
+ PYBAMM_DISABLE_TELEMETRY="true"
PYBAMM_USE_VCPKG=ON
VCPKG_ROOT_DIR=C:\vcpkg
VCPKG_DEFAULT_TRIPLET=x64-windows-static-md
@@ -92,7 +94,7 @@ jobs:
python -c "import pybamm; print(pybamm.IDAKLUSolver())"
python -m pytest -m cibw {project}/tests/unit
- name: Upload Windows wheels
- uses: actions/upload-artifact@v4.3.6
+ uses: actions/upload-artifact@v4.4.3
with:
name: wheels_windows
path: ./wheelhouse/*.whl
@@ -116,6 +118,8 @@ jobs:
- name: Build wheels on Linux
run: pipx run cibuildwheel --output-dir wheelhouse
env:
+ CIBW_ENVIRONMENT: >
+ PYBAMM_DISABLE_TELEMETRY="true"
CIBW_ARCHS_LINUX: x86_64
CIBW_BEFORE_ALL_LINUX: >
yum -y install openblas-devel lapack-devel &&
@@ -129,7 +133,7 @@ jobs:
python -m pytest -m cibw {project}/tests/unit
- name: Upload wheels for Linux
- uses: actions/upload-artifact@v4.3.6
+ uses: actions/upload-artifact@v4.4.3
with:
name: wheels_manylinux
path: ./wheelhouse/*.whl
@@ -242,7 +246,9 @@ jobs:
python scripts/install_KLU_Sundials.py
python -m cibuildwheel --output-dir wheelhouse
env:
- # 10.13 for Intel (macos-12/macos-13), 11.0 for Apple Silicon (macos-14 and macos-latest)
+ CIBW_ENVIRONMENT: >
+ PYBAMM_DISABLE_TELEMETRY="true"
+ # 10.13 for Intel (macos-13), 11.0 for Apple Silicon (macos-14 and macos-latest)
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.os == 'macos-14' && '11.0' || '10.13' }}
CIBW_ARCHS_MACOS: auto
CIBW_BEFORE_BUILD: python -m pip install cmake casadi setuptools wheel delocate
@@ -261,7 +267,7 @@ jobs:
python -m pytest -m cibw {project}/tests/unit
- name: Upload wheels for macOS (amd64, arm64)
- uses: actions/upload-artifact@v4.3.6
+ uses: actions/upload-artifact@v4.4.3
with:
name: wheels_${{ matrix.os }}
path: ./wheelhouse/*.whl
@@ -281,7 +287,7 @@ jobs:
run: pipx run build --sdist
- name: Upload SDist
- uses: actions/upload-artifact@v4.3.6
+ uses: actions/upload-artifact@v4.4.3
with:
name: sdist
path: ./dist/*.tar.gz
diff --git a/.github/workflows/release_reminder.yml b/.github/workflows/release_reminder.yml
deleted file mode 100644
index f838c8d57a..0000000000
--- a/.github/workflows/release_reminder.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-name: Create a release reminder
-
-on:
- schedule:
- # Run at 10 am UTC on days-of-month 1 and 28 in January, May, and September.
- - cron: "0 10 1,28 1,5,9 *"
-
-permissions:
- contents: read
- issues: write
-
-jobs:
- remind:
- if: github.repository_owner == 'pybamm-team'
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: JasonEtco/create-an-issue@v2
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- filename: .github/release_reminder.md
diff --git a/.github/workflows/run_benchmarks_over_history.yml b/.github/workflows/run_benchmarks_over_history.yml
index d01564b210..28960fb4da 100644
--- a/.github/workflows/run_benchmarks_over_history.yml
+++ b/.github/workflows/run_benchmarks_over_history.yml
@@ -18,6 +18,10 @@ on:
ncommits:
description: "Number of commits to benchmark between commit_start and commit_end"
default: "100"
+
+env:
+ PYBAMM_DISABLE_TELEMETRY: "true"
+
jobs:
benchmarks:
runs-on: ubuntu-latest
@@ -46,7 +50,7 @@ jobs:
${{ github.event.inputs.commit_start }}..${{ github.event.inputs.commit_end }}
- name: Upload results as artifact
- uses: actions/upload-artifact@v4.3.6
+ uses: actions/upload-artifact@v4.4.3
with:
name: asv_over_history_results
path: results
diff --git a/.github/workflows/run_periodic_tests.yml b/.github/workflows/run_periodic_tests.yml
index 9f10a9c6f7..bb164e9351 100644
--- a/.github/workflows/run_periodic_tests.yml
+++ b/.github/workflows/run_periodic_tests.yml
@@ -13,6 +13,7 @@ on:
- cron: "0 3 * * *"
env:
+ PYBAMM_DISABLE_TELEMETRY: "true"
FORCE_COLOR: 3
PYBAMM_IDAKLU_EXPR_CASADI: ON
PYBAMM_IDAKLU_EXPR_IREE: ON
@@ -31,7 +32,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [ ubuntu-latest, macos-12, macos-14, windows-latest ]
+ os: [ ubuntu-latest, macos-13, macos-14, windows-latest ]
python-version: [ "3.9", "3.10", "3.11", "3.12" ]
name: Tests (${{ matrix.os }} / Python ${{ matrix.python-version }})
@@ -46,7 +47,7 @@ jobs:
sudo apt-get install gfortran gcc graphviz pandoc libopenblas-dev texlive-latex-extra dvipng
- name: Install macOS system dependencies
- if: matrix.os == 'macos-12' || matrix.os == 'macos-14'
+ if: matrix.os == 'macos-13' || matrix.os == 'macos-14'
env:
HOMEBREW_NO_INSTALL_CLEANUP: 1
HOMEBREW_NO_AUTO_UPDATE: 1
@@ -89,7 +90,7 @@ jobs:
- name: Upload coverage report
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
- uses: codecov/codecov-action@v4.5.0
+ uses: codecov/codecov-action@v5.0.2
with:
token: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 8b33553737..6d38fcadb6 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -59,7 +59,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
- uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
+ uses: actions/upload-artifact@184d73b71b93c222403b2e7f1ffebe4508014249 # v4.4.1
with:
name: SARIF file
path: results.sarif
@@ -68,6 +68,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5
+ uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4
with:
sarif_file: results.sarif
diff --git a/.github/workflows/test_on_push.yml b/.github/workflows/test_on_push.yml
index 9224b7df36..d54259bbd3 100644
--- a/.github/workflows/test_on_push.yml
+++ b/.github/workflows/test_on_push.yml
@@ -5,6 +5,7 @@ on:
pull_request:
env:
+ PYBAMM_DISABLE_TELEMETRY: "true"
FORCE_COLOR: 3
PYBAMM_IDAKLU_EXPR_CASADI: ON
PYBAMM_IDAKLU_EXPR_IREE: ON
@@ -36,12 +37,11 @@ jobs:
pre-commit run -a
run_unit_integration_and_coverage_tests:
- needs: style
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
- os: [ubuntu-latest, macos-12, macos-14, windows-latest]
+ os: [ubuntu-latest, macos-13, macos-14, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12"]
name: Tests (${{ matrix.os }} / Python ${{ matrix.python-version }})
@@ -65,7 +65,7 @@ jobs:
sudo apt-get install libopenblas-dev texlive-latex-extra dvipng
- name: Install macOS system dependencies
- if: matrix.os == 'macos-12' || matrix.os == 'macos-14'
+ if: matrix.os == 'macos-13' || matrix.os == 'macos-14'
env:
HOMEBREW_NO_INSTALL_CLEANUP: 1
HOMEBREW_NO_AUTO_UPDATE: 1
@@ -123,7 +123,7 @@ jobs:
- name: Upload coverage report
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
- uses: codecov/codecov-action@v4.5.0
+ uses: codecov/codecov-action@v5.0.2
with:
token: ${{ secrets.CODECOV_TOKEN }}
@@ -132,7 +132,6 @@ jobs:
# Skips IDAKLU module compilation for speedups, which is already tested in other jobs.
run_doctests:
- needs: style
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -177,7 +176,6 @@ jobs:
run: python -m nox -s docs
run_example_tests:
- needs: style
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -233,7 +231,6 @@ jobs:
run: python -m nox -s examples
run_scripts_tests:
- needs: style
runs-on: ubuntu-latest
strategy:
fail-fast: false
diff --git a/.github/workflows/work_precision_sets.yml b/.github/workflows/work_precision_sets.yml
index fafc5b1738..5810956786 100644
--- a/.github/workflows/work_precision_sets.yml
+++ b/.github/workflows/work_precision_sets.yml
@@ -5,6 +5,9 @@ on:
types: [published]
workflow_dispatch:
+env:
+ PYBAMM_DISABLE_TELEMETRY: "true"
+
jobs:
benchmarks_on_release:
if: github.repository_owner == 'pybamm-team'
@@ -27,7 +30,7 @@ jobs:
python benchmarks/work_precision_sets/time_vs_reltols.py
python benchmarks/work_precision_sets/time_vs_abstols.py
- name: Create Pull Request
- uses: peter-evans/create-pull-request@v6
+ uses: peter-evans/create-pull-request@v7
with:
delete-branch: true
branch-suffix: short-commit-hash
diff --git a/.gitignore b/.gitignore
index 42c76b7c55..8632f96d30 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,7 +46,6 @@ input/*
# simulation outputs
out/
-config.py
matplotlibrc
*.pickle
*.sav
@@ -65,6 +64,7 @@ coverage.xml
htmlcov/
# virtual environment
+.venv
env/
venv/
venv3.5/
diff --git a/.lycheeignore b/.lycheeignore
index 55a4a4c623..929fe36475 100644
--- a/.lycheeignore
+++ b/.lycheeignore
@@ -15,3 +15,6 @@ file:///home/runner/work/PyBaMM/PyBaMM/docs/source/user_guide/fundamentals/pybam
# Errors in docs/source/user_guide/index.md
file:///home/runner/work/PyBaMM/PyBaMM/docs/source/user_guide/api_docs
+
+# Telemetry
+https://us.i.posthog.com
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 43928bbc56..fa5a7336f3 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -4,7 +4,7 @@ ci:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: "v0.6.3"
+ rev: "v0.7.4"
hooks:
- id: ruff
args: [--fix, --show-fixes]
@@ -13,13 +13,13 @@ repos:
types_or: [python, pyi, jupyter]
- repo: https://github.com/adamchainz/blacken-docs
- rev: "1.18.0"
+ rev: "1.19.1"
hooks:
- id: blacken-docs
additional_dependencies: [black==23.*]
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.6.0
+ rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f5a959748f..b273435dff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,54 @@
# [Unreleased](https://github.com/pybamm-team/PyBaMM/)
+# [v24.11.0](https://github.com/pybamm-team/PyBaMM/tree/v24.11.0) - 2024-11-20
+
+## Features
+
+- Added `CoupledVariable` which provides a placeholder variable whose equation can be elsewhere in the model. ([#4556](https://github.com/pybamm-team/PyBaMM/pull/4556))
+- Adds support to `pybamm.Experiment` for the `output_variables` option in the `IDAKLUSolver`. ([#4534](https://github.com/pybamm-team/PyBaMM/pull/4534))
+- Adds an option "voltage as a state" that can be "false" (default) or "true". If "true" adds an explicit algebraic equation for the voltage. ([#4507](https://github.com/pybamm-team/PyBaMM/pull/4507))
+- Improved `QuickPlot` accuracy for simulations with Hermite interpolation. ([#4483](https://github.com/pybamm-team/PyBaMM/pull/4483))
+- 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 basic telemetry to record which functions are being run. See [Telemetry section in the User Guide](https://docs.pybamm.org/en/latest/source/user_guide/index.html#telemetry) for more information. ([#4441](https://github.com/pybamm-team/PyBaMM/pull/4441))
+- 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 ([#4369](https://github.com/pybamm-team/PyBaMM/pull/4369))
+- Added a lithium ion equivalent circuit model with split open circuit voltages for each electrode (`SplitOCVR`). ([#4330](https://github.com/pybamm-team/PyBaMM/pull/4330))
+- Added the `pybamm.DiscreteTimeSum` expression node to sum an expression over a sequence of data times, and accompanying `pybamm.DiscreteTimeData` class to store the data times and values ([#4501](https://github.com/pybamm-team/PyBaMM/pull/4501))
+
+## Optimizations
+
+- Performance refactor of JAX BDF Solver with default Jax method set to `"BDF"`. ([#4456](https://github.com/pybamm-team/PyBaMM/pull/4456))
+- Improved performance of initialization and reinitialization of ODEs in the (`IDAKLUSolver`). ([#4453](https://github.com/pybamm-team/PyBaMM/pull/4453))
+- Removed the `start_step_offset` setting and disabled minimum `dt` warnings for drive cycles with the (`IDAKLUSolver`). ([#4416](https://github.com/pybamm-team/PyBaMM/pull/4416))
+
+## Bug Fixes
+- Added error for binary operators on two concatenations with different numbers of children. Previously, the extra children were dropped. Also fixed bug where Q_rxn was dropped from the total heating term in half-cell models. ([#4562](https://github.com/pybamm-team/PyBaMM/pull/4562))
+- Fixed bug where Q_rxn was set to 0 for the negative electrode in half-cell models. ([#4557](https://github.com/pybamm-team/PyBaMM/pull/4557))
+- Fixed bug in post-processing solutions with infeasible experiments using the (`IDAKLUSolver`). ([#4541](https://github.com/pybamm-team/PyBaMM/pull/4541))
+- Disabled IREE on MacOS due to compatibility issues and added the CasADI
+ path to the environment to resolve issues on MacOS and Linux. Windows
+ users may still experience issues with interpolation. ([#4528](https://github.com/pybamm-team/PyBaMM/pull/4528))
+- Added `_from_json()` functionality to `Sign` which was erroneously omitted previously. ([#4517](https://github.com/pybamm-team/PyBaMM/pull/4517))
+- Fixed bug where IDAKLU solver failed when `output variables` were specified and an extrapolation event is present. ([#4440](https://github.com/pybamm-team/PyBaMM/pull/4440))
+
+## Breaking changes
+
+- Deprecated `pybamm.Simulation.set_parameters` and `pybamm.Simulation. set_up_and_parameterise_experiment` functions in `pybamm.simulation.py`. ([#3752](https://github.com/pybamm-team/PyBaMM/pull/3752))
+- Removed all instances of `param = self.param` and now directly access `self.param` across the codebase. This change simplifies parameter references and enhances readability. ([#4484](https://github.com/pybamm-team/PyBaMM/pull/4494))
+- Removed the deprecation warning for the chemistry argument in
+ ParameterValues ([#4466](https://github.com/pybamm-team/PyBaMM/pull/4466))
+- The parameters "... electrode OCP entropic change [V.K-1]" and "... electrode volume change" are now expected to be functions of stoichiometry only instead of functions of both stoichiometry and maximum concentration ([#4427](https://github.com/pybamm-team/PyBaMM/pull/4427))
+- Renamed `set_events` function to `add_events_from` to better reflect its purpose. ([#4421](https://github.com/pybamm-team/PyBaMM/pull/4421))
+
# [v24.9.0](https://github.com/pybamm-team/PyBaMM/tree/v24.9.0) - 2024-09-03
## Features
- Added additional user-configurable options to the (`IDAKLUSolver`) and adjusted the default values to improve performance. ([#4282](https://github.com/pybamm-team/PyBaMM/pull/4282))
- Added the diffusion element to be used in the Thevenin model. ([#4254](https://github.com/pybamm-team/PyBaMM/pull/4254))
+- Added lumped surface thermal model ([#4203](https://github.com/pybamm-team/PyBaMM/pull/4203))
## Optimizations
diff --git a/CITATION.cff b/CITATION.cff
index d128cf485e..aee304dbde 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -24,6 +24,6 @@ keywords:
- "expression tree"
- "python"
- "symbolic differentiation"
-version: "24.9.0"
+version: "24.11.0"
repository-code: "https://github.com/pybamm-team/PyBaMM"
title: "Python Battery Mathematical Modelling (PyBaMM)"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ad56ac34ca..ec594e5ca5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,7 +19,7 @@ endif()
project(idaklu)
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
@@ -82,6 +82,8 @@ pybind11_add_module(idaklu
src/pybamm/solvers/c_solvers/idaklu/idaklu_solver.hpp
src/pybamm/solvers/c_solvers/idaklu/IDAKLUSolver.cpp
src/pybamm/solvers/c_solvers/idaklu/IDAKLUSolver.hpp
+ src/pybamm/solvers/c_solvers/idaklu/IDAKLUSolverGroup.cpp
+ src/pybamm/solvers/c_solvers/idaklu/IDAKLUSolverGroup.hpp
src/pybamm/solvers/c_solvers/idaklu/IDAKLUSolverOpenMP.inl
src/pybamm/solvers/c_solvers/idaklu/IDAKLUSolverOpenMP.hpp
src/pybamm/solvers/c_solvers/idaklu/IDAKLUSolverOpenMP_solvers.cpp
@@ -94,6 +96,8 @@ pybind11_add_module(idaklu
src/pybamm/solvers/c_solvers/idaklu/common.cpp
src/pybamm/solvers/c_solvers/idaklu/Solution.cpp
src/pybamm/solvers/c_solvers/idaklu/Solution.hpp
+ src/pybamm/solvers/c_solvers/idaklu/SolutionData.cpp
+ src/pybamm/solvers/c_solvers/idaklu/SolutionData.hpp
src/pybamm/solvers/c_solvers/idaklu/Options.hpp
src/pybamm/solvers/c_solvers/idaklu/Options.cpp
# IDAKLU expressions / function evaluation [abstract]
@@ -101,6 +105,8 @@ pybind11_add_module(idaklu
src/pybamm/solvers/c_solvers/idaklu/Expressions/Base/Expression.hpp
src/pybamm/solvers/c_solvers/idaklu/Expressions/Base/ExpressionSet.hpp
src/pybamm/solvers/c_solvers/idaklu/Expressions/Base/ExpressionTypes.hpp
+ src/pybamm/solvers/c_solvers/idaklu/observe.hpp
+ src/pybamm/solvers/c_solvers/idaklu/observe.cpp
# IDAKLU expressions - concrete implementations
${IDAKLU_EXPR_CASADI_SOURCE_FILES}
${IDAKLU_EXPR_IREE_SOURCE_FILES}
@@ -138,6 +144,23 @@ set_target_properties(
INSTALL_RPATH_USE_LINK_PATH TRUE
)
+# openmp
+if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+ execute_process(
+ COMMAND "brew" "--prefix"
+ OUTPUT_VARIABLE HOMEBREW_PREFIX
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (OpenMP_ROOT)
+ set(OpenMP_ROOT "${OpenMP_ROOT}:${HOMEBREW_PREFIX}/opt/libomp")
+ else()
+ set(OpenMP_ROOT "${HOMEBREW_PREFIX}/opt/libomp")
+ endif()
+endif()
+find_package(OpenMP)
+if(OpenMP_CXX_FOUND)
+ target_link_libraries(idaklu PRIVATE OpenMP::OpenMP_CXX)
+endif()
+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR})
# Sundials
find_package(SUNDIALS REQUIRED)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 556a732518..eb510f7054 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -44,7 +44,7 @@ You now have everything you need to start making changes!
### B. Writing your code
-6. PyBaMM is developed in [Python](https://www.python.org)), and makes heavy use of [NumPy](https://numpy.org/) (see also [NumPy for MatLab users](https://numpy.org/doc/stable/user/numpy-for-matlab-users.html) and [Python for R users](https://www.rebeccabarter.com/blog/2023-09-11-from_r_to_python)).
+6. PyBaMM is developed in [Python](https://www.python.org), and makes heavy use of [NumPy](https://numpy.org/).
7. Make sure to follow our [coding style guidelines](#coding-style-guidelines).
8. Commit your changes to your branch with [useful, descriptive commit messages](https://chris.beams.io/posts/git-commit/): Remember these are
publicly visible and should still make sense a few months ahead in time.
@@ -116,8 +116,8 @@ PyBaMM provides a utility function `import_optional_dependency`, to check for th
Optional dependencies should never be imported at the module level, but always inside methods. For example:
-```
-def use_pybtex(x,y,z):
+```python
+def use_pybtex(x, y, z):
pybtex = import_optional_dependency("pybtex")
...
```
@@ -468,8 +468,8 @@ Editable notebooks are made available using [Google Colab](https://colab.researc
GitHub does some magic with particular filenames. In particular:
-- The first page people see when they go to [our GitHub page](https://github.com/pybamm-team/PyBaMM) displays the contents of [README.md](https://github.com/pybamm-team/PyBaMM/blob/develop/README.md), which is written in the [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) format. Some guidelines can be found [here](https://help.github.com/articles/about-readmes/).
-- The license for using PyBaMM is stored in [LICENSE](https://github.com/pybamm-team/PyBaMM/blob/develop/LICENSE.txt), and [automatically](https://help.github.com/articles/adding-a-license-to-a-repository/) linked to by GitHub.
+- The first page people see when they go to [our GitHub page](https://github.com/pybamm-team/PyBaMM) displays the contents of [README.md](https://github.com/pybamm-team/PyBaMM/blob/develop/README.md), which is written in the [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) format. Some guidelines can be found [here](https://docs.github.com/articles/about-readmes/).
+- The license for using PyBaMM is stored in [LICENSE](https://github.com/pybamm-team/PyBaMM/blob/develop/LICENSE.txt), and [automatically](https://docs.github.com/articles/adding-a-license-to-a-repository/) linked to by GitHub.
- This file, [CONTRIBUTING.md](https://github.com/pybamm-team/PyBaMM/blob/develop/CONTRIBUTING.md) is recognised as the contribution guidelines and a link is [automatically](https://github.com/blog/1184-contributing-guidelines) displayed when new issues or pull requests are created.
## Acknowledgements
diff --git a/README.md b/README.md
index a904e5a67c..2b5250d856 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/pybamm-team/PyBaMM/badge)](https://scorecard.dev/viewer/?uri=github.com/pybamm-team/PyBaMM)
-[![All Contributors](https://img.shields.io/badge/all_contributors-90-orange.svg)](#-contributors)
+[![All Contributors](https://img.shields.io/badge/all_contributors-93-orange.svg)](#-contributors)
diff --git a/all_contributors.md b/all_contributors.md
index 9bb1e373d5..d4a41ba8e1 100644
--- a/all_contributors.md
+++ b/all_contributors.md
@@ -91,7 +91,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Agnik Bakshi 📖 |
RuiheLi 💻 ⚠️ |
chmabaur 🐛 💻 |
- Abhishek Chaudhari 📖 💻 |
+ Abhishek Chaudhari 📖 💻 ⚠️ |
Shubham Bhardwaj 🚇 |
Jonathan Lauber 🚇 |
@@ -120,6 +120,11 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Ubham16 💻 |
Mehrdad Babazadeh 💻 ⚠️ |
Pip Liggins 💻 ⚠️ |
+ Medha Bhardwaj 💻 |
+
+
+ Marc Berliner 💻 📖 🚇 🚧 |
+ Aswinr24 ⚠️ |
diff --git a/conftest.py b/conftest.py
index 7ac6cf3c74..77513d56db 100644
--- a/conftest.py
+++ b/conftest.py
@@ -51,3 +51,8 @@ def set_random_seed():
@pytest.fixture(autouse=True)
def set_debug_value():
pybamm.settings.debug_mode = True
+
+
+@pytest.fixture(autouse=True)
+def disable_telemetry():
+ pybamm.telemetry.disable()
diff --git a/docs/conf.py b/docs/conf.py
index 55a4ac3f61..76dcffb18b 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -341,7 +341,7 @@
{% set github_docname =
'github/pybamm-team/pybamm/blob/develop/docs/' +
-env.doc2path(env.docname, base=None) %}
+env.doc2path(env.docname, base=None) | string() %}
{% set notebooks_version = env.config.html_context.notebooks_version %}
{% set github_download_url = env.config.html_context.github_download_url %}
diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst
index 33be0235a7..4667752157 100644
--- a/docs/source/api/index.rst
+++ b/docs/source/api/index.rst
@@ -9,10 +9,10 @@ API documentation
:Release: |version|
:Date: |today|
-This reference manual details functions, modules, and objects
-included in PyBaMM, describing what they are and what they do.
+This reference manual details the classes, functions, modules, and objects included in PyBaMM, describing what they are and what they do.
For a high-level introduction to PyBaMM, see the :ref:`user guide ` and the :ref:`examples `.
+
.. toctree::
:maxdepth: 2
diff --git a/docs/source/api/models/lithium_ion/ecm_split_ocv.rst b/docs/source/api/models/lithium_ion/ecm_split_ocv.rst
new file mode 100644
index 0000000000..a7d833cf55
--- /dev/null
+++ b/docs/source/api/models/lithium_ion/ecm_split_ocv.rst
@@ -0,0 +1,7 @@
+Equivalent Circuit Model with Split OCV (SplitOCVR)
+=====================================================
+
+.. autoclass:: pybamm.lithium_ion.SplitOCVR
+ :members:
+
+.. footbibliography::
diff --git a/docs/source/api/models/lithium_ion/index.rst b/docs/source/api/models/lithium_ion/index.rst
index 1a72c3c662..52efe44d6b 100644
--- a/docs/source/api/models/lithium_ion/index.rst
+++ b/docs/source/api/models/lithium_ion/index.rst
@@ -12,3 +12,4 @@ Lithium-ion Models
msmr
yang2017
electrode_soh
+ ecm_split_ocv
diff --git a/docs/source/api/util.rst b/docs/source/api/util.rst
index 824ec6126d..9cf8d09470 100644
--- a/docs/source/api/util.rst
+++ b/docs/source/api/util.rst
@@ -19,3 +19,5 @@ Utility functions
.. autofunction:: pybamm.has_jax
.. autofunction:: pybamm.is_jax_compatible
+
+.. autofunction:: pybamm.set_logging_level
diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst
index a5958b327b..6ddaf5867e 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
@@ -67,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
@@ -85,6 +87,7 @@ The notebooks are organised into subfolders, and can be viewed in the galleries
notebooks/parameterization/change-input-current.ipynb
notebooks/parameterization/parameter-values.ipynb
notebooks/parameterization/parameterization.ipynb
+ notebooks/parameterization/sensitivities_and_data_fitting.ipynb
.. nbgallery::
:caption: Simulations and Experiments
diff --git a/docs/source/examples/notebooks/getting_started/tutorial-4-setting-parameter-values.ipynb b/docs/source/examples/notebooks/getting_started/tutorial-4-setting-parameter-values.ipynb
index a35a81932f..02206d4210 100644
--- a/docs/source/examples/notebooks/getting_started/tutorial-4-setting-parameter-values.ipynb
+++ b/docs/source/examples/notebooks/getting_started/tutorial-4-setting-parameter-values.ipynb
@@ -25,18 +25,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "\n",
- "\u001B[1m[\u001B[0m\u001B[34;49mnotice\u001B[0m\u001B[1;39;49m]\u001B[0m\u001B[39;49m A new release of pip is available: \u001B[0m\u001B[31;49m23.3.1\u001B[0m\u001B[39;49m -> \u001B[0m\u001B[32;49m24.0\u001B[0m\n",
- "\u001B[1m[\u001B[0m\u001B[34;49mnotice\u001B[0m\u001B[1;39;49m]\u001B[0m\u001B[39;49m To update, run: \u001B[0m\u001B[32;49mpip install --upgrade pip\u001B[0m\n",
"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": [
@@ -74,7 +64,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "The parameter values are stored in a dictionary"
+ "The parameter values are stored in a dictionary-like object of class [`pybamm.ParameterValues`](https://docs.pybamm.org/en/latest/source/api/parameters/parameter_values.html). "
]
},
{
@@ -98,8 +88,8 @@
" 'EC initial concentration in electrolyte [mol.m-3]': 4541.0,\n",
" 'Electrode height [m]': 0.065,\n",
" 'Electrode width [m]': 1.58,\n",
- " 'Electrolyte conductivity [S.m-1]': ,\n",
- " 'Electrolyte diffusivity [m2.s-1]': ,\n",
+ " 'Electrolyte conductivity [S.m-1]': ,\n",
+ " 'Electrolyte diffusivity [m2.s-1]': ,\n",
" 'Electron charge [C]': 1.602176634e-19,\n",
" 'Faraday constant [C.mol-1]': 96485.33212,\n",
" 'Ideal gas constant [J.K-1.mol-1]': 8.314462618,\n",
@@ -125,14 +115,14 @@
" 'Negative current collector thickness [m]': 1.2e-05,\n",
" 'Negative electrode Bruggeman coefficient (electrode)': 0,\n",
" 'Negative electrode Bruggeman coefficient (electrolyte)': 1.5,\n",
- " 'Negative electrode OCP [V]': ,\n",
+ " 'Negative electrode OCP [V]': ,\n",
" 'Negative electrode OCP entropic change [V.K-1]': 0.0,\n",
" 'Negative electrode active material volume fraction': 0.75,\n",
" 'Negative electrode charge transfer coefficient': 0.5,\n",
" 'Negative electrode conductivity [S.m-1]': 215.0,\n",
" 'Negative electrode density [kg.m-3]': 1657.0,\n",
" 'Negative electrode double-layer capacity [F.m-2]': 0.2,\n",
- " 'Negative electrode exchange-current density [A.m-2]': ,\n",
+ " 'Negative electrode exchange-current density [A.m-2]': ,\n",
" 'Negative electrode porosity': 0.25,\n",
" 'Negative electrode reaction-driven LAM factor [m3.mol-1]': 0.0,\n",
" 'Negative electrode specific heat capacity [J.kg-1.K-1]': 700.0,\n",
@@ -155,14 +145,14 @@
" 'Positive current collector thickness [m]': 1.6e-05,\n",
" 'Positive electrode Bruggeman coefficient (electrode)': 0,\n",
" 'Positive electrode Bruggeman coefficient (electrolyte)': 1.5,\n",
- " 'Positive electrode OCP [V]': ,\n",
+ " 'Positive electrode OCP [V]': ,\n",
" 'Positive electrode OCP entropic change [V.K-1]': 0.0,\n",
" 'Positive electrode active material volume fraction': 0.665,\n",
" 'Positive electrode charge transfer coefficient': 0.5,\n",
" 'Positive electrode conductivity [S.m-1]': 0.18,\n",
" 'Positive electrode density [kg.m-3]': 3262.0,\n",
" 'Positive electrode double-layer capacity [F.m-2]': 0.2,\n",
- " 'Positive electrode exchange-current density [A.m-2]': ,\n",
+ " 'Positive electrode exchange-current density [A.m-2]': ,\n",
" 'Positive electrode porosity': 0.335,\n",
" 'Positive electrode reaction-driven LAM factor [m3.mol-1]': 0.0,\n",
" 'Positive electrode specific heat capacity [J.kg-1.K-1]': 700.0,\n",
@@ -243,8 +233,8 @@
"output_type": "stream",
"text": [
"EC initial concentration in electrolyte [mol.m-3]\t4541.0\n",
- "Electrolyte conductivity [S.m-1]\t\n",
- "Electrolyte diffusivity [m2.s-1]\t\n",
+ "Electrolyte conductivity [S.m-1]\t\n",
+ "Electrolyte diffusivity [m2.s-1]\t\n",
"Initial concentration in electrolyte [mol.m-3]\t1000.0\n",
"Negative electrode Bruggeman coefficient (electrolyte)\t1.5\n",
"Positive electrode Bruggeman coefficient (electrolyte)\t1.5\n",
@@ -274,12 +264,12 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "2ac62159d85445f0b021b8800750726f",
+ "model_id": "5dd5facebda342afa83dca4f0838788c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
- "interactive(children=(FloatSlider(value=0.0, description='t', max=3555.448018330181, step=35.55448018330181), …"
+ "interactive(children=(FloatSlider(value=0.0, description='t', max=3555.448018679505, step=35.55448018679505), …"
]
},
"metadata": {},
@@ -288,7 +278,7 @@
{
"data": {
"text/plain": [
- ""
+ ""
]
},
"execution_count": 6,
@@ -324,55 +314,58 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "| Parameter | Type of parameter |\n",
- "| ========================================================= | =========================================================================================================================================================================================================== |\n",
- "| Maximum concentration in positive electrode [mol.m-3] | Parameter |\n",
- "| Maximum concentration in negative electrode [mol.m-3] | Parameter |\n",
- "| Nominal cell capacity [A.h] | Parameter |\n",
- "| Electrode width [m] | Parameter |\n",
- "| Positive electrode Bruggeman coefficient (electrode) | Parameter |\n",
- "| Faraday constant [C.mol-1] | Parameter |\n",
- "| Number of electrodes connected in parallel to make a cell | Parameter |\n",
- "| Negative electrode Bruggeman coefficient (electrode) | Parameter |\n",
- "| Initial concentration in electrolyte [mol.m-3] | Parameter |\n",
- "| Electrode height [m] | Parameter |\n",
- "| Lower voltage cut-off [V] | Parameter |\n",
- "| Upper voltage cut-off [V] | Parameter |\n",
- "| Negative electrode Bruggeman coefficient (electrolyte) | Parameter |\n",
- "| Separator Bruggeman coefficient (electrolyte) | Parameter |\n",
- "| Number of cells connected in series to make a battery | Parameter |\n",
- "| Ideal gas constant [J.K-1.mol-1] | Parameter |\n",
- "| Positive electrode thickness [m] | Parameter |\n",
- "| Reference temperature [K] | Parameter |\n",
- "| Initial temperature [K] | Parameter |\n",
- "| Positive electrode Bruggeman coefficient (electrolyte) | Parameter |\n",
- "| Negative electrode thickness [m] | Parameter |\n",
- "| Separator thickness [m] | Parameter |\n",
- "| Electrolyte conductivity [S.m-1] | FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Temperature [K]' |\n",
- "| Positive electrode OCP [V] | FunctionParameter with inputs(s) 'Positive particle stoichiometry' |\n",
- "| Negative particle radius [m] | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |\n",
- "| Positive electrode OCP entropic change [V.K-1] | FunctionParameter with inputs(s) 'Positive particle stoichiometry', 'Maximum positive particle surface concentration [mol.m-3]' |\n",
- "| Negative electrode porosity | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |\n",
- "| Positive particle radius [m] | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |\n",
- "| Positive electrode active material volume fraction | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |\n",
- "| Ambient temperature [K] | FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]' |\n",
- "| Initial concentration in positive electrode [mol.m-3] | FunctionParameter with inputs(s) 'Radial distance (r) [m]', 'Through-cell distance (x) [m]' |\n",
- "| Cation transference number | FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Temperature [K]' |\n",
- "| Negative electrode OCP [V] | FunctionParameter with inputs(s) 'Negative particle stoichiometry' |\n",
- "| Negative particle diffusivity [m2.s-1] | FunctionParameter with inputs(s) 'Negative particle stoichiometry', 'Temperature [K]' |\n",
- "| Thermodynamic factor | FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Temperature [K]' |\n",
- "| Positive electrode exchange-current density [A.m-2] | FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Positive particle surface concentration [mol.m-3]', 'Maximum positive particle surface concentration [mol.m-3]', 'Temperature [K]' |\n",
- "| Negative electrode active material volume fraction | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |\n",
- "| Positive particle diffusivity [m2.s-1] | FunctionParameter with inputs(s) 'Positive particle stoichiometry', 'Temperature [K]' |\n",
- "| Positive electrode porosity | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |\n",
- "| Positive electrode conductivity [S.m-1] | FunctionParameter with inputs(s) 'Temperature [K]' |\n",
- "| Initial concentration in negative electrode [mol.m-3] | FunctionParameter with inputs(s) 'Radial distance (r) [m]', 'Through-cell distance (x) [m]' |\n",
- "| Negative electrode OCP entropic change [V.K-1] | FunctionParameter with inputs(s) 'Negative particle stoichiometry', 'Maximum negative particle surface concentration [mol.m-3]' |\n",
- "| Current function [A] | FunctionParameter with inputs(s) 'Time [s]' |\n",
- "| Electrolyte diffusivity [m2.s-1] | FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Temperature [K]' |\n",
- "| Separator porosity | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |\n",
- "| Negative electrode exchange-current density [A.m-2] | FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Negative particle surface concentration [mol.m-3]', 'Maximum negative particle surface concentration [mol.m-3]', 'Temperature [K]' |\n",
- "| Negative electrode conductivity [S.m-1] | FunctionParameter with inputs(s) 'Temperature [K]' |\n"
+ "┌───────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐\n",
+ "│ Parameter │ Type of parameter │\n",
+ "├───────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤\n",
+ "│ Positive electrode Bruggeman coefficient (electrode) │ Parameter │\n",
+ "│ Faraday constant [C.mol-1] │ Parameter │\n",
+ "│ Separator Bruggeman coefficient (electrolyte) │ Parameter │\n",
+ "│ Reference temperature [K] │ Parameter │\n",
+ "│ Upper voltage cut-off [V] │ Parameter │\n",
+ "│ Lower voltage cut-off [V] │ Parameter │\n",
+ "│ Negative electrode thickness [m] │ Parameter │\n",
+ "│ Initial concentration in electrolyte [mol.m-3] │ Parameter │\n",
+ "│ Nominal cell capacity [A.h] │ Parameter │\n",
+ "│ Number of electrodes connected in parallel to make a cell │ Parameter │\n",
+ "│ Negative electrode Bruggeman coefficient (electrolyte) │ Parameter │\n",
+ "│ Separator thickness [m] │ Parameter │\n",
+ "│ Initial temperature [K] │ Parameter │\n",
+ "│ Maximum concentration in negative electrode [mol.m-3] │ Parameter │\n",
+ "│ Positive electrode Bruggeman coefficient (electrolyte) │ Parameter │\n",
+ "│ Positive electrode thickness [m] │ Parameter │\n",
+ "│ Ideal gas constant [J.K-1.mol-1] │ Parameter │\n",
+ "│ Maximum concentration in positive electrode [mol.m-3] │ Parameter │\n",
+ "│ Electrode height [m] │ Parameter │\n",
+ "│ Electrode width [m] │ Parameter │\n",
+ "│ Negative electrode Bruggeman coefficient (electrode) │ Parameter │\n",
+ "│ Number of cells connected in series to make a battery │ Parameter │\n",
+ "│ Negative electrode porosity │ FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' │\n",
+ "│ Positive particle radius [m] │ FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' │\n",
+ "│ Positive electrode OCP [V] │ FunctionParameter with inputs(s) 'Positive particle stoichiometry' │\n",
+ "│ Negative electrode OCP entropic change [V.K-1] │ FunctionParameter with inputs(s) 'Negative particle stoichiometry' │\n",
+ "│ Initial concentration in positive electrode [mol.m-3] │ FunctionParameter with inputs(s) 'Radial distance (r) [m]', 'Through-cell distance (x) [m]' │\n",
+ "│ Positive electrode conductivity [S.m-1] │ FunctionParameter with inputs(s) 'Temperature [K]' │\n",
+ "│ Negative electrode active material volume fraction │ FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' │\n",
+ "│ Negative particle diffusivity [m2.s-1] │ FunctionParameter with inputs(s) 'Negative particle stoichiometry', 'Temperature [K]' │\n",
+ "│ Initial concentration in negative electrode [mol.m-3] │ FunctionParameter with inputs(s) 'Radial distance (r) [m]', 'Through-cell distance (x) [m]' │\n",
+ "│ Positive electrode porosity │ FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' │\n",
+ "│ Positive electrode OCP entropic change [V.K-1] │ FunctionParameter with inputs(s) 'Positive particle stoichiometry' │\n",
+ "│ Electrolyte conductivity [S.m-1] │ FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Temperature [K]' │\n",
+ "│ Thermodynamic factor │ FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Temperature [K]' │\n",
+ "│ Electrolyte diffusivity [m2.s-1] │ FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Temperature [K]' │\n",
+ "│ Negative particle radius [m] │ FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' │\n",
+ "│ Negative electrode OCP [V] │ FunctionParameter with inputs(s) 'Negative particle stoichiometry' │\n",
+ "│ Cation transference number │ FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Temperature [K]' │\n",
+ "│ Ambient temperature [K] │ FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]' │\n",
+ "│ Current function [A] │ FunctionParameter with inputs(s) 'Time [s]' │\n",
+ "│ Negative electrode exchange-current density [A.m-2] │ FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Negative particle surface concentration [mol.m-3]', 'Maximum negative particle surface concentration [mol.m-3]', 'Temperature [K]' │\n",
+ "│ Negative electrode conductivity [S.m-1] │ FunctionParameter with inputs(s) 'Temperature [K]' │\n",
+ "│ Positive electrode exchange-current density [A.m-2] │ FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Positive particle surface concentration [mol.m-3]', 'Maximum positive particle surface concentration [mol.m-3]', 'Temperature [K]' │\n",
+ "│ Separator porosity │ FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' │\n",
+ "│ Positive electrode active material volume fraction │ FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' │\n",
+ "│ Positive particle diffusivity [m2.s-1] │ FunctionParameter with inputs(s) 'Positive particle stoichiometry', 'Temperature [K]' │\n",
+ "└───────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\n",
+ "\n"
]
}
],
@@ -424,12 +417,12 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "29a3805ee040456bbe863a52cc423492",
+ "model_id": "48c0f7150c154399b1d56dadd90a41ad",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
- "interactive(children=(FloatSlider(value=0.0, description='t', max=1703.071841649571, step=17.03071841649571), …"
+ "interactive(children=(FloatSlider(value=0.0, description='t', max=1703.0716533945217, step=17.030716533945217)…"
]
},
"metadata": {},
@@ -438,7 +431,7 @@
{
"data": {
"text/plain": [
- ""
+ ""
]
},
"execution_count": 9,
@@ -510,7 +503,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "f362d8ff79bc4b868f59470d58fdd9c6",
+ "model_id": "b8992b55090149ea932deb091190b655",
"version_major": 2,
"version_minor": 0
},
@@ -524,7 +517,7 @@
{
"data": {
"text/plain": [
- ""
+ ""
]
},
"execution_count": 11,
@@ -539,6 +532,49 @@
"sim.plot([\"Current [A]\", \"Voltage [V]\"])"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Input parameters\n",
+ "\n",
+ "If the value of a parameter is expected to change often (e.g. running a parameter sweep) is is more convenient to set a parameter as an \"input parameter\". This is a placeholder that can be filled in with a numerical value when the model is solved.\n",
+ "\n",
+ "To set a parameter as an input parameter, we can set its value to the string `[input]` in the parameter values dictionary. For example, we can set the `Current function [A]` to be an input parameter and then run a parameter sweep over different current values like so:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ "