Skip to content
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
425af11
Add support for uniform grid sizing across subdomains (#720) (#5253)
swastim01 Nov 15, 2025
6ba2cde
Fix typo in Butler-Volmer equation docstring (#5279)
cnaples79 Nov 16, 2025
e893156
fix bug with bulk ocp lithiation (#5280)
rtimms Nov 18, 2025
6c8cbfd
doc: fix typo in concentration description in notebook (#5284)
gregordecristoforo Nov 19, 2025
af64ddd
Merge pull request #5276 from pybamm-team/main
valentinsulzer Nov 19, 2025
2d6d111
Merge branch 'main' of https://github.com/pybamm-team/PyBaMM
DrSOKane Mar 13, 2026
11c20cd
Refactored porosity change in terms of concentration, not thickness
DrSOKane Mar 17, 2026
8d55d1b
c_sei is always a size-average quantity now
DrSOKane Mar 17, 2026
5529bfd
tidied up example notebook
DrSOKane Mar 17, 2026
58d9fd8
Merge branch 'main' of https://github.com/pybamm-team/PyBaMM into rec…
DrSOKane Mar 17, 2026
9526deb
style: pre-commit fixes
pre-commit-ci[bot] Mar 17, 2026
f7799d9
removed duplicate compute_var_pts_from_thicknesses
DrSOKane Mar 17, 2026
9806aa5
Merge branch 'recode-porosity-change' of https://github.com/DrSOKane/…
DrSOKane Mar 17, 2026
6f6aa08
Removed tests that check for non-implementation of the implemented fe…
DrSOKane Mar 18, 2026
96c68b9
Merge branch 'main' into recode-porosity-change
rtimms Mar 19, 2026
6ed2701
merge main, rerun notebook
rtimms Mar 19, 2026
8ea44a3
Merge branch 'main' of https://github.com/pybamm-team/PyBaMM into rec…
DrSOKane Mar 20, 2026
a77bea3
synced coupled coupled degradation notebook with main
DrSOKane Mar 20, 2026
86740f5
Merge branch 'recode-porosity-change' of https://github.com/DrSOKane/…
DrSOKane Mar 20, 2026
5d02e5e
Updated formation-storage-loss notebook to account for breaking change
DrSOKane Mar 24, 2026
293e654
changelog
DrSOKane Mar 24, 2026
8a739a4
style: pre-commit fixes
pre-commit-ci[bot] Mar 24, 2026
41d2221
Copilot suggestions, these ones were actually good
DrSOKane Mar 24, 2026
889ee8b
Merge branch 'recode-porosity-change' of https://github.com/DrSOKane/…
DrSOKane Mar 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Features

- Porosity change now works for particle size distributions ([#5417](https://github.com/pybamm-team/PyBaMM/pull/5417))
- Improved the performance of processed variables by replacing `casadi.vertcat` input stacking with numpy vectors. ([#5413](https://github.com/pybamm-team/PyBaMM/pull/5413))
- Preserve custom variables and events in built-in model to_config ([#5411](https://github.com/pybamm-team/PyBaMM/pull/5411))
- Allow out of bounds initial state of charge to enable initialising a simulation at a voltage outside the voltage limits. ([#5386](https://github.com/pybamm-team/PyBaMM/pull/5386))
Expand All @@ -18,12 +19,14 @@ as initial conditions. ([#5311](https://github.com/pybamm-team/PyBaMM/pull/5311)

## Bug fixes

- SEI concentration is always a size-averaged quantity if particle size distribution present ([#5417](https://github.com/pybamm-team/PyBaMM/pull/5417))
- Fixed a bug in the exchange current density calculation for MSMR models. ([#5404](https://github.com/pybamm-team/PyBaMM/pull/5404))
- Fixed a bug where when converting `ExpressionFunctionParameter` to source code, `Interpolant` objects were being reduced to just their input variable names (e.g., sto) instead of preserving the full constructor call with data arrays. ([#5393](https://github.com/pybamm-team/PyBaMM/pull/5393))
- Fixed a bug when using 2 phases with particle size distribution the bounds of the particle size distribution were always taken from the primary phase. ([#5415](https://github.com/pybamm-team/PyBaMM/pull/5415))

## Breaking changes

- Porosity change no longer excludes initial SEI thickness, i.e. the initial SEI now takes up space. ([#5417](https://github.com/pybamm-team/PyBaMM/pull/5417))
- The mass matrix inverse is no longer computed during discretisation. Solvers instead use sparse linear solves. ([#5391](https://github.com/pybamm-team/PyBaMM/pull/5391))
- Dropped JAX support on macOS with Intel (x86_64) processors. JAX dropped macOS Intel wheels in version 0.5.0, and the minimum JAX version has been bumped to >=0.7.0 for Python 3.14 compatibility. macOS users require Apple Silicon (M-series) for JAX features. ([#5374](https://github.com/pybamm-team/PyBaMM/pull/5374))
- Added a small regularisation term to the exchange current density which slightly modifies the functional form of the kinetics as stoichiometry approaches 0 or 1. ([#5371](https://github.com/pybamm-team/PyBaMM/pull/5371))
Expand Down

Large diffs are not rendered by default.

10 changes: 0 additions & 10 deletions src/pybamm/models/full_battery_models/base_battery_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,16 +631,6 @@ def __init__(self, extra_options):

# Options not yet compatible with particle-size distributions
if options["particle size"] == "distribution":
if options["lithium plating porosity change"] != "false":
raise pybamm.OptionError(
"Lithium plating porosity change not yet supported for particle-size"
" distributions."
)
if options["SEI porosity change"] == "true":
raise NotImplementedError(
"SEI porosity change submodels do not yet support particle-size "
"distributions."
)
if options["heat of mixing"] != "false":
raise NotImplementedError(
"Heat of mixing submodels do not yet support particle-size "
Expand Down
8 changes: 3 additions & 5 deletions src/pybamm/models/submodels/interface/sei/base_sei.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,9 @@ def _get_standard_concentration_variables(self, c_sei):
}
else:
# c_sei is a bulk quantity [mol.m-3]
if self.size_distribution:
c_sei_sav = pybamm.size_average(c_sei)
c_sei_xav = pybamm.x_average(c_sei_sav)
else:
c_sei_xav = pybamm.x_average(c_sei)
if self.size_distribution is True:
c_sei = pybamm.size_average(c_sei)
c_sei_xav = pybamm.x_average(c_sei)
c_sei_av = pybamm.yz_average(c_sei_xav)
variables = {
f"{Domain} {self.reaction_name}concentration [mol.m-3]": c_sei,
Expand Down
49 changes: 22 additions & 27 deletions src/pybamm/models/submodels/porosity/reaction_driven_porosity.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def get_coupled_variables(self, variables):
dom = domain.split()[0]
Domain = dom.capitalize()
SEI_option = getattr(self.options, dom)["SEI"]
plating_option = getattr(self.options, dom)["lithium plating"]
phases_option = getattr(self.options, dom)["particle phases"]
phases = self.options.phases[dom]
for phase in phases:
Expand All @@ -42,40 +43,34 @@ def get_coupled_variables(self, variables):
# `domain` has more than one phase
phase_name = phase + " "
pref = phase.capitalize() + ": "
Comment on lines 43 to 45
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module header / class docstring still describes porosity change “as a multiple of SEI/plating thicknesses”, but the implementation now uses concentrations and partial molar volumes. Consider updating those docstrings/comments to match the new approach to avoid misleading documentation.

Copilot uses AI. Check for mistakes.
a_k = variables[
f"{Domain} electrode {phase_name}"
"surface area to volume ratio [m-1]"
]
if SEI_option == "none":
L_sei_0 = pybamm.Scalar(0)
V_bar_sei = pybamm.Scalar(0)
else:
V_bar_sei = pybamm.Parameter(
f"{pref}SEI partial molar volume [m3.mol-1]"
)
if plating_option == "none":
V_bar_Li = pybamm.Scalar(0)
else:
L_sei_0 = pybamm.Parameter(f"{pref}Initial SEI thickness [m]")
L_sei_k = variables[f"{Domain} {phase_name}SEI thickness [m]"]
L_pl_k = variables[
f"{Domain} {phase_name}lithium plating thickness [m]"
V_bar_Li = pybamm.Parameter(
"Lithium metal partial molar volume [m3.mol-1]"
)
c_sei_k = variables[
f"{Domain} {phase_name}SEI concentration [mol.m-3]"
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lithium metal partial molar volume is already available on the parameter set (self.param.V_bar_Li) and is used that way elsewhere (e.g. lithium plating submodels). Creating a new pybamm.Parameter(...) here duplicates the symbol and makes the code less consistent; prefer reusing self.param.V_bar_Li.

Suggested change
V_bar_Li = pybamm.Parameter(
"Lithium metal partial molar volume [m3.mol-1]"
)
c_sei_k = variables[
f"{Domain} {phase_name}SEI concentration [mol.m-3]"
V_bar_Li = self.param.V_bar_Li
c_sei_k = variables[
f"{Domain} {phase_name}SEI concentration [mol.m-3]"
f"{Domain} {phase_name}SEI concentration [mol.m-3]"

Copilot uses AI. Check for mistakes.
]
L_dead_k = variables[
f"{Domain} {phase_name}dead lithium thickness [m]"
c_sei_cr_k = variables[
f"{Domain} {phase_name}SEI on cracks concentration [mol.m-3]"
]
L_sei_cr_k = variables[
f"{Domain} {phase_name}SEI on cracks thickness [m]"
c_sei_tot_k = c_sei_k + c_sei_cr_k
c_pl_k = variables[
f"{Domain} {phase_name}lithium plating concentration [mol.m-3]"
]
roughness_k = variables[
f"{Domain} {phase_name}electrode roughness ratio"
c_dead_k = variables[
f"{Domain} {phase_name}dead lithium concentration [mol.m-3]"
]
c_pl_tot_k = c_pl_k + c_dead_k

L_tot = (
(L_sei_k - L_sei_0)
+ L_pl_k
+ L_dead_k
+ L_sei_cr_k * (roughness_k - 1)
)

# This assumes a thin film so curvature effects are neglected.
# They could be included (e.g. for a sphere it is
# a_n * (L_tot + L_tot ** 2 / R_n + L_tot ** # 3 / (3 * R_n ** 2)))
# but it is not clear if it is relevant or not.
delta_eps_k += -a_k * L_tot
delta_eps_k += V_bar_sei * c_sei_tot_k + V_bar_Li * c_pl_tot_k

domain_param = self.param.domain_params[domain.split()[0]]
eps_k = domain_param.epsilon_init + delta_eps_k
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,6 @@ def test_options(self):
"plating porosity change"
}
)
with pytest.raises(pybamm.OptionError, match=r"distributions"):
pybamm.BaseBatteryModel(
{
"particle size": "distribution",
"lithium plating porosity change": "true",
}
)

Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test that enforced an OptionError for particle size: distribution + lithium plating porosity change: true was removed, but there isn’t an added test confirming this configuration is now valid (e.g. model can be instantiated/built). Consider adding a positive test case here to lock in the new supported behavior.

Suggested change
# valid combination of particle size distribution and lithium plating porosity change
pybamm.BaseBatteryModel(
{
"particle size": "distribution",
"lithium plating": "reversible",
"lithium plating porosity change": "true",
}
)

Copilot uses AI. Check for mistakes.
# contact resistance
with pytest.raises(pybamm.OptionError, match=r"contact resistance"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,6 @@ def test_nonspherical_particle_not_implemented(self):
with pytest.raises(NotImplementedError):
pybamm.lithium_ion.MPM(options)

def test_reversible_plating_with_porosity_not_implemented(self):
options = {
"lithium plating": "reversible",
"lithium plating porosity change": "true",
}
with pytest.raises(pybamm.OptionError, match=r"distributions"):
pybamm.lithium_ion.MPM(options)

def test_msmr(self):
options = {
"open-circuit potential": "MSMR",
Expand Down Expand Up @@ -166,11 +158,3 @@ def test_interstitial_diffusion_limited(self):
options = {"SEI": "interstitial-diffusion limited"}
model = pybamm.lithium_ion.MPM(options)
model.check_well_posedness()

def test_ec_reaction_limited_not_implemented(self):
options = {
"SEI": "ec reaction limited",
"SEI porosity change": "true",
}
with pytest.raises(NotImplementedError):
pybamm.lithium_ion.MPM(options)
Loading