Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 4884 unify hysteresis #4893

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft

Conversation

rtimms
Copy link
Contributor

@rtimms rtimms commented Mar 5, 2025

Description

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" (currently hard-coded to be the mean of the delithaiton and lithiation branches)
  • 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.
  • Allow optional passing of a "... electrode OCP [V]" parameter to use as the equilibrium OCP and compute it as the mean of the two branches if unspecified, so that the breaking change arises only when it was actively specified. We don't currently have cases of having defaults for missing parameters, and my experience in the past is that it is better to be explicit. My preference would be either 1) always require "... electrode OCP [V]" to be provided, or 2) compute it as the mean. The current implementation does the latter.

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 96.02649% with 6 lines in your changes missing coverage. Please review.

Project coverage is 98.68%. Comparing base (998c18f) to head (81f1058).

Files with missing lines Patch % Lines
...rc/pybamm/models/submodels/thermal/base_thermal.py 81.25% 6 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #4893      +/-   ##
===========================================
- Coverage    98.71%   98.68%   -0.03%     
===========================================
  Files          304      305       +1     
  Lines        23495    23479      -16     
===========================================
- Hits         23193    23171      -22     
- Misses         302      308       +6     

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

@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.

"source": [
"## Model Equations\n",
"\n",
"Herein, we outline the equations for the \"Curret Sigmoid\" model, as described in Ai et al. (2022), the Differential Capacity Hysteresis State open-circuit potential model, as described in Wycisk (2022), and the Hysteresis State open-circuit potential model, as described in Axen (2022).\n",

Choose a reason for hiding this comment

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

typo: "Curret" -> "Current"

"\n",
"$$U = \\frac{1+h}{2} U_{delith} + \\frac{1-h}{2} U_{lith},$$\n",
"\n",
"where $h$ is a hysteresis state variable, $U_{delith}$ is the delithiation open-circuit potential, and $U_{lith}$ is the lithiation open-circuit potential. The hysteresis state variable $h$ is defined between -1 and 1, where -1 corresponds to the delithiation branch and 1 corresponds to the lithiation branch.\n",

Choose a reason for hiding this comment

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

Definition of $h$ is back-to-front in text vs equation.

"\n",
"In all of the models, the open-circuit potential is given by\n",
"\n",
"$$U = \\frac{1+h}{2} U_{delith} + \\frac{1-h}{2} U_{lith},$$\n",

Choose a reason for hiding this comment

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

Prefer throughout to use Roman (non-italic) text for textual subscripts.

"$$ U = \\text{sigmoid}\\left(-\\frac{KI}{Q_{cell}}\\right) U_{delith} + \\text{sigmoid}\\left(\\frac{KI}{Q_{cell}}\\right) U_{lith}\n",
"$$\n",
"\n",
"Where $K$ is a fitting parameter, $I$ is the cell current, and $Q_{cell}$ is the cell capacity. To simplify the comparison with the other models, we can rewrite this expression in terms of the hysteresis state variable $h$ given by\n",

Choose a reason for hiding this comment

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

I suggest to use another symbol for $K$ to avoid confusion with rate parameters in other models.

Since the current sigmoid '$K$' is hardcoded in the implementation, quote the value here and perhaps consider the current lower bound (C/1000? C/1e6?) at which the current sigmoid implementation will noticeably no longer obey the intended relation, due to the finite step window.

"\n",
"### Hysteresis State Variable (Axen)\n",
"In this model, the state variable $h(z,t)$ is both stoichiometry and time-dependent, and is governed by the following ODEs:\n",
"$$ \\frac{dh(z,t)}{dt} = K_{lith} \\, \\frac{I_{cell}}{Q_{cell}} \\, (1 - h(z,t)) \\qquad \\text{for lithiation}$$\n",

Choose a reason for hiding this comment

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

Even if this is how it's presented in the original literature, it's inherently confusing that the implied range of $h$ is -0.5 to +0.5 here, but -1 to 1 for the general model.

I would recommend that we use this document to collectively paraphrase all the original literature models into a common notation and definition. Do not worry about exactly how the original authors approached symbols or factorisation. The main point of this document should be for PyBaMM users to distinguish the various model options, and understand their basis in scientific literature where appropriate.

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.

2 participants