Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# [Unreleased](https://github.com/pybamm-team/PyBaMM/)

## Features

- Step `duration`, `period` and `temperature` accept a `pybamm.Parameter` or `pybamm.InputParameter` ([#5744](https://github.com/pybamm-team/PyBaMM/pull/5744))
- Added `SymbolicTermination`: terminate a step on any inequality over model variables ([#5744](https://github.com/pybamm-team/PyBaMM/pull/5744))

## Bug fixes

- The `integration` nox session no longer installs the `pydiffsol` extra on macOS Intel CI runners, where it has no working build. ([#5726](https://github.com/pybamm-team/PyBaMM/pull/5726))
Expand All @@ -8,6 +13,8 @@

## Features

- Experiment steps accept a symbolic `duration` (e.g. a `pybamm.InputParameter`), resolved against the inputs passed to `Simulation.solve`, so one built model serves any duration. Drive cycles now repeat by wrapping the step time, rather than being tiled out to a fixed duration.
- Experiment steps accept a symbolic inequality as a `termination`, e.g. `pybamm.CoupledVariable("Voltage [V]") > pybamm.InputParameter("Voltage hold [V]")`, so a cut-off can be set on any model variable and its threshold supplied at solve time.
- Added unstructured mesh support (`UnstructuredSubMesh`, generators, and interface coupling) for arbitrary 2D/3D domains. Hexahedra must have planar faces (warped hexes raise a `GeometryError`), and `UserSuppliedUnstructuredMesh` accepts tetrahedral, triangular, and quadrilateral cells only. ([#5687](https://github.com/pybamm-team/PyBaMM/pull/5687))
- Generalised `VectorField` to N components and added `Component`/`Norm` operators for multi-dimensional vector fields. ([#5686](https://github.com/pybamm-team/PyBaMM/pull/5686))
- Removed the left sidebar from the documentation home page for a cleaner landing experience. ([#5699](https://github.com/pybamm-team/PyBaMM/pull/5699))
Expand Down
5 changes: 5 additions & 0 deletions docs/source/api/experiment/experiment_steps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ Custom steps can be defined using either explicit or implicit control:
Step terminations
-----------------

Any inequality over model variables can terminate a step:

.. autoclass:: pybamm.step.SymbolicTermination
:members:

Standard step termination events are implemented by the following classes, which are
called when the termination is specified by a specific string. These classes can be
either be called directly or via the string format specified in the class docstring
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"source": [
"## Custom termination\n",
"\n",
"Termination of a step can be specified using a few standard strings (e.g. \"4.2V\" for voltage, \"1 A\" for current, \"C/2\" for C-rate), or via a custom termination step. The custom termination step can be specified based on any variable in the model.\n",
"Termination of a step can be specified using a few standard strings (e.g. \"4.2V\" for voltage, \"1 A\" for current, \"C/2\" for C-rate), or as an inequality on any model variable, referenced by name with `pybamm.CoupledVariable`. The threshold can be a number, a `pybamm.Parameter` or a `pybamm.InputParameter`.\n",
"Below, we show an example where we specify a custom termination step based on keeping the anode potential above 0V, which is a common limit used to avoid lithium plating,"
]
},
Expand Down Expand Up @@ -63,16 +63,9 @@
"parameter_values = pybamm.ParameterValues(\"Chen2020\")\n",
"\n",
"\n",
"# Create a custom termination event for the anode potential cut-off at 0.02V\n",
"# Terminate when the anode potential drops to 0.02V\n",
"# We use 0.02V instead of 0V to give a safety factor\n",
"def anode_potential_cutoff(variables):\n",
" return variables[\"Anode potential [V]\"] - 0.02\n",
"\n",
"\n",
"# The CustomTermination class takes a name and function\n",
"anode_potential_termination = pybamm.step.CustomTermination(\n",
" name=\"Anode potential cut-off [V]\", event_function=anode_potential_cutoff\n",
")\n",
"anode_potential_termination = pybamm.CoupledVariable(\"Anode potential [V]\") < 0.02\n",
"\n",
"# Provide a list of termination events, each step will stop whenever the first\n",
"# termination event is reached\n",
Expand Down
18 changes: 1 addition & 17 deletions packages/pybamm/src/pybamm/discretisations/discretisation.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,23 +300,7 @@ def _resolve_coupled_variables_in_model(self, model):
"""Resolve CoupledVariables in rhs, algebraic, initial_conditions, and boundary_conditions."""

def resolve_symbol(symbol):
if isinstance(symbol, pybamm.CoupledVariable):
if symbol.name not in model.variables:
raise pybamm.DiscretisationError(
f"CoupledVariable '{symbol.name}' not found in model.variables."
)
return resolve_symbol(model.variables[symbol.name])
elif hasattr(symbol, "children") and symbol.children:
new_children = []
changed = False
for child in symbol.children:
new_child = resolve_symbol(child)
new_children.append(new_child)
if new_child is not child:
changed = True
if changed:
return symbol.create_copy(new_children=new_children)
return symbol
return pybamm.SymbolProcessor.resolve(symbol, model.variables)

for var, expr in list(model.rhs.items()):
resolved = resolve_symbol(expr)
Expand Down
2 changes: 1 addition & 1 deletion packages/pybamm/src/pybamm/experiment/step/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .steps import *
from .base_step import BaseStep, BaseStepExplicit, BaseStepImplicit
from .step_termination import BaseTermination, CurrentTermination, VoltageTermination, CustomTermination, CRateTermination, CrateTermination, _read_termination
from .step_termination import BaseTermination, CurrentTermination, VoltageTermination, SymbolicTermination, CustomTermination, CRateTermination, CrateTermination, _read_termination

__all__ = ['base_step', 'step_termination', 'steps']
Loading
Loading