Skip to content

Conversation

rtimms
Copy link
Contributor

@rtimms rtimms commented Mar 5, 2025

Description

Fixes #5038
Fixes #5081
Fixes #5021

Unifies the hysteresis models in PyBaMM and adds heat generation due to hysteresis. In particular:

  • Adds a new BaseHysteresisOpenCircuitPotential class that sets variables for the lithiation and delithiation OCP, as well as the average (simply the mean), and the hysteresis voltage (H = U_lith - U_delith).
  • Makes sure all models, even CurrentSigmoidOpenCircuitPotential, are expressed in terms of a hysteresis state variable -1<h<1
  • Allows the initial hysteresis state to be a function of position through the electrode
  • Allows the hysteresis decay rates of the Axen and Wycisk models to be a function of stoichiometry and temperature
  • Adds a heat source term in each active material phase Q_hys = i_vol * (U - U_eq) where i_vol is the volumetric interfacial current density, U is the OCP (i.e. includes hysteresis), and U_eq is the "equilibrium OCP"
  • Renames the notebook differential-capacity-hysteresis-state.ipynb tohysteresis-state-models.ipynb and extends it to include a comparison of all of the existing hysteresis models

Related #4884

What this doesn't do from #4884:

  • Reformulate the Wycisk model to use $\gamma = K \cdot \left(\frac{\frac{\partial q_\mathrm{vol}}{\partial U}}{\left.\frac{\partial q_\mathrm{vol}}{\partial U}\right|_\mathrm{ref}}\right)^{-n}$. This would be breaking as it requires rescaling parameters. Is this a breaking change worth making? Changes to parameters have, in the past, been problematic/easy for users to miss.
  • Express all the models simply as $\frac{\partial h}{\partial t} = \gamma\cdot\left(\frac{i_\mathrm{surf}a_\mathrm{vol}}{\phi_\mathrm{act}Fc_\mathrm{max}}\right)\cdot \left(1 - \mathrm{sgn}(i_\mathrm{surf})h\right)$ using the base class, and then specify \gamma in the subclasses. This would be an easy change to make, but I'm not sure it is much harder to just specify the whole rhs in the base class and it makes the code more readable (even if there is some repetition). The way it currently is, you see the whole ODE in the set_rhs method and don't need to chase back to the base class. Happy to take input on this.

Breaking

  • Need to explicitly give the equilibrium, delithiation, and lithiation OCPs when using a hysteresis model. E.g. you must provide all three of "Negative electrode OCP [V]", "Negative electrode delithiation OCP [V]", and "Negative electrode lithiation OCP [V]"

Type of change

Please add a line in the relevant section of CHANGELOG.md to document the change (include PR #)

Important checks:

Please confirm the following before marking the PR as ready for review:

  • No style issues: nox -s pre-commit
  • All tests pass: nox -s tests
  • The documentation builds: nox -s doctests
  • Code is commented for hard-to-understand areas
  • Tests added that prove fix is effective or that feature works

@rtimms rtimms requested a review from a team as a code owner March 5, 2025 09:33
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@rtimms rtimms marked this pull request as draft March 5, 2025 09:33
@rtimms
Copy link
Contributor Author

rtimms commented Mar 5, 2025

@ejfdickinson would appreciate your feedback on this

Copy link

codecov bot commented Mar 5, 2025

Codecov Report

Attention: Patch coverage is 97.76119% with 6 lines in your changes missing coverage. Please review.

Project coverage is 99.09%. Comparing base (509def8) to head (3869f0a).
Report is 3 commits behind head on develop.

Files with missing lines Patch % Lines
...m/models/full_battery_models/base_battery_model.py 83.78% 6 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #4893      +/-   ##
===========================================
- Coverage    99.12%   99.09%   -0.03%     
===========================================
  Files          305      306       +1     
  Lines        23604    23659      +55     
===========================================
+ Hits         23397    23446      +49     
- Misses         207      213       +6     

☔ View full report in Codecov by Sentry.
📢 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.

@ejfdickinson
Copy link

ejfdickinson commented Mar 11, 2025

@rtimms I'll look over it.

Relating to #4884 incomplete items currently excluded from the PR:

  • If the breaking change to introduce a reference value is unappetising (fair enough), I recommend that we consider this a "specification bug fix" where we redefine from

    $\left(\frac{\partial q_\mathrm{vol}}{\partial U}\right)^{-n}$

    to

    $\left(\frac{\frac{\partial q_\mathrm{vol}}{\partial U}}{C_\mathrm{ref,vol}}\right)^{-n}$

    where $C_\mathrm{ref,vol}$ is (implicitly) hardcoded = 1 F/m3. Then the equation has legitimate unit syntax but the implementation in code doesn't need altering.

  • Current approach (avoid inheriting an equation using $\gamma$ from the base class) is fine imo.

  • In my view we should prefer a solution with future-proofed flexibility for the true equilibrium OCP to be unequal to the mean of the two branches. Not doing this now is just storing another breaking change for the future, isn't it? From my opinion and in terms of my use cases, I'd be ok to suck up a breaking change that impacts the lumped heat source. Of course, it'd be good to check this against a general policy.

Copy link

@ejfdickinson ejfdickinson left a comment

Choose a reason for hiding this comment

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

In addition to specific comments on the docs, one additional comment:

  • Should we use this as an opportunity to move from arbitrary author-name definitions to more descriptive inputs options, e.g.

"Axen" -> "one-state"
"Wycisk" -> "one-state differential capacity"

and similarly for module names? Although they may be the original reports, I don't think that "Axen" or "Wycisk" are really that intuitively descriptive for what are actually quite general hysteresis descriptions.

@rtimms
Copy link
Contributor Author

rtimms commented Jun 23, 2025

To do:

Fix #5038

and

-Should we use this as an opportunity to move from arbitrary author-name definitions to more descriptive inputs options, e.g.
"Axen" -> "one-state"
"Wycisk" -> "one-state differential capacity"

@rtimms rtimms marked this pull request as ready for review June 27, 2025 16:40
Copy link
Contributor

@aabills aabills left a comment

Choose a reason for hiding this comment

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

Overall looks fine. Forgive my ignorance, but Wycisk/Axen are specific cases of the "new models" right? In that case, should they be kept as options to make this a non-breaking change? In any case, I don't think they should be both kept as subclasses and deleted as options -- I'd be surprised if there are any users that use submodels directly rather than going through the options, so this effectively just creates non-accessible code.

Copy link
Member

@valentinsulzer valentinsulzer left a comment

Choose a reason for hiding this comment

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

Looks good, a couple of minor comments for the notebook.
I also prefer the previous names (Axen/Wycisk) over the new names which are a real mouthful, but not a strong opinion

@kratman
Copy link
Contributor

kratman commented Jul 2, 2025

I am looking into the docs failure now, probably something pretty minor

@kratman
Copy link
Contributor

kratman commented Jul 2, 2025

I am looking into the docs failure now, probably something pretty minor

I pushed a temporary fix for the failing citation so that review could continue, I will push a in a real fix once I get it working again

@kratman
Copy link
Contributor

kratman commented Jul 2, 2025

Docs are fixed now. I also updated the description to make sure all tickets get closed

@rtimms
Copy link
Contributor Author

rtimms commented Jul 4, 2025

I also prefer the previous names (Axen/Wycisk) over the new names which are a real mouthful, but not a strong opinion

The argument for them is that they at least infer what the model is from the option. I don't think the option names are so much of a mouthful ("one-state hysteresis"), but I agree the classes could be shortened.

@rtimms
Copy link
Contributor Author

rtimms commented Jul 7, 2025

@aabills I removed the factor of 2 so that the model implementation is non-breaking. Passing the old option names now logs a warning and renames them to the new names. "Axen"-->"one-state hysteresis" and "Wycisk"->"one-state differential capacity hysteresis". The models are the same equations, just expressed in a more unified way.

@rtimms rtimms requested review from aabills and ejfdickinson July 7, 2025 11:09
Copy link
Contributor

@aabills aabills left a comment

Choose a reason for hiding this comment

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

Thanks!

@kratman kratman merged commit f04a1f8 into develop Jul 8, 2025
35 of 38 checks passed
@kratman kratman deleted the issue-4884-unify-hysteresis branch July 8, 2025 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants