Skip to content

fix: rename composite ESOH phase-capacity inputs off the MSMR name pattern - #5738

Open
rtimms wants to merge 5 commits into
mainfrom
fix/composite-esoh-input-names
Open

fix: rename composite ESOH phase-capacity inputs off the MSMR name pattern#5738
rtimms wants to merge 5 commits into
mainfrom
fix/composite-esoh-input-names

Conversation

@rtimms

@rtimms rtimms commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes #5737.

Description

electrode_soh_composite named its phase-capacity InputParameters Q_n_1 / Q_p_1 / Q_n_2 / Q_p_2. Those match the deprecated-MSMR name pattern in msmr.py:

^(X|Q|w|U0|a|j0_ref)_(n|p)(_[ld])?_[0-9]+$

so when the inputs reach ParameterValues.check_parameter_values via BaseSolver._set_up_model_inputs, the deprecation branch fires. Two effects, on every composite / multi-phase initial-state solve:

  1. A DeprecationWarning telling the user to rename a parameter they never set and cannot change — it names PyBaMM's own internal input.
  2. A phantom key added to the returned dict: values[new_param] = values.get(param) adds e.g. Negative electrode host site occupancy capacity (1) [A.h] alongside Q_n_1. On this path it goes no further — _set_up_model_inputs keeps only the names the model declares, so the phantom entry is discarded before the solver sees it. The warning is the whole user-visible symptom; I overstated this in the issue and have corrected it there.

The collision is accidental: the composite Q_n_1 is a phase capacity (primary/secondary particle), the MSMR Q_n_1 is a host site capacity.

Fix

Rename to Q_n_prim / Q_n_sec / Q_p_prim / Q_p_sec, which matches the prim/sec vocabulary already used for the phases (param.n.prim, param.n.sec) and the existing symbol-suffix convention elsewhere (R_n_prim in standard_spatial_vars, the var_pts keys).

On whether this is breaking. No documented API takes these names: solve_split, solve_full, and get_initial_stoichiometries_composite all build them internally from parameter_values, their inputs kwarg is a different namespace (it is forwarded to parameter_values.evaluate), and the returned dicts hold only stoichiometries. They do not appear in summary_variables (all 102 use display names) or in the user model's solution.all_inputs ([{}]).

They are visible in one place, so I would not call them unreachable: the ESOH sub-simulation's solution, which a caller can hold via the public esoh_sim kwarg on solve_full

ElectrodeSOHComposite.solve_full(0.5, pvals, options=options, esoh_sim=esoh_sim)
esoh_sim.solution.all_inputs
# [{'Q_Li': [...], 'Q_n_1': [...], 'Q_n_2': [...], 'Q_p_1': [...], 'SOC_init': [...]}]

Reading those keys is introspection rather than a documented contract, and code that does it fails with a loud KeyError rather than silently wrong numbers, so I have treated this as non-breaking and spelled the old -> new mapping out in the CHANGELOG instead. Happy to be overruled.

I also considered aligning with the "Primary: Negative electrode capacity [A.h]" convention and did not: PHASE_NAMES = ["Primary: ", "Secondary: "] (parameters/bpx.py:95) builds ParameterValues keys, whereas these are InputParameter names sitting in all_inputs next to Q_Li, V_init, SOC_init, and z_1. A long display-style string there would be the only one of its kind and would read as a parameter-set key.

Note the names are also built dynamically at _get_electrode_capacity_equation (f"Q_{e}_1" / f"Q_{e}_2"), which a grep for the literal strings misses; both forms are updated.

Narrowing _VALID_NAME_RE instead would be wrong: Q_n_1 genuinely is a legacy MSMR name, so the check is correct on the name it is handed. The problem was that the composite path chose that name for something else.

Verification

Before, on main:

import warnings, pybamm

model = pybamm.lithium_ion.SPMe({"particle phases": ("2", "1")})
sim = pybamm.Simulation(model, parameter_values=pybamm.ParameterValues("Chen2020_composite"))
with warnings.catch_warnings(record=True) as caught:
    warnings.simplefilter("always")
    sim.solve([0, 10], initial_soc="2.8 V")
print(len([w for w in caught if issubclass(w.category, DeprecationWarning)]))
# 3   ->   0 with this branch

Added TestElectrodeSOHComposite::test_phase_capacity_inputs_are_not_deprecated_msmr_names, which fails on main and passes here.

Local runs (tests/unit/test_models, test_parameters, test_simulation.py, test_base_simulation.py, test_experiments, test_serialisation, test_batch_study.py): 2770 passed, 13 skipped. test_solvers/test_idaklu_jax.py fails identically on unmodified main in my environment, so it is untouched by this change and left to CI.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • No style issues: nox -s pre-commit
  • All tests pass: nox -s tests (see note above on the environmental idaklu_jax failures)
  • The documentation builds: nox -s doctests — not run; no docs touched
  • Code is commented for hard-to-understand areas
  • Tests added that prove the fix is effective

…ttern

The composite electrode-SOH model named its phase-capacity input parameters
Q_n_1 / Q_p_1 / Q_n_2 / Q_p_2. Those match the deprecated-MSMR name pattern in
msmr.py, so check_parameter_values reported every composite solve as using a
renamed parameter -- naming an internal input the caller never set and cannot
change -- and injected a phantom "... host site occupancy capacity (N) [A.h]"
key into the solver inputs alongside it.

The names are internal to electrode_soh_composite: built there, consumed there.
Renaming them to Q_n_prim / Q_n_sec / Q_p_prim / Q_p_sec matches the prim/sec
vocabulary already used for the phases (param.n.prim, param.n.sec) and leaves
the MSMR check to fire only on real MSMR names.

Fixes #5737

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@rtimms
rtimms requested a review from a team as a code owner August 31, 2026 10:58
rtimms and others added 2 commits August 31, 2026 11:58
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Asserting that no DeprecationWarning at all escapes a composite solve made the
test answerable by any third-party deprecation. Match the rename message
instead, which is the warning the collision actually produces.

Also drop the changelog's claim that the phantom renamed key reaches the
solver: _set_up_model_inputs keeps only the names the model declares, so it is
discarded. The warning was the whole user-visible symptom.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Matching any "has been renamed to" warning made the test answerable by an
unrelated deprecation in the parameter set -- as "electrode diffusivity" ->
"particle diffusivity" would be, from the same call site.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.54839% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.20%. Comparing base (78fe10a) to head (7c62e60).

Files with missing lines Patch % Lines
...tery_models/lithium_ion/electrode_soh_composite.py 93.54% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5738      +/-   ##
==========================================
+ Coverage   98.12%   98.20%   +0.08%     
==========================================
  Files         340      340              
  Lines       32743    32743              
==========================================
+ Hits        32128    32156      +28     
+ Misses        615      587      -28     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The keys show up in all_inputs on the ESOH sub-simulation's solution, which a
caller can hold via the public esoh_sim kwarg, so anyone introspecting them
needs the mapping rather than a description of the fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Composite ElectrodeSOH input parameters (Q_n_1 etc.) collide with the legacy MSMR name pattern

1 participant