Models

The models module provides PyBaMM model classes and utilities for adding design variables and computing metrics.

Model Classes

class ionworkspipeline.data_fits.models.GITTModel(options=None, name='GITT model')

Diffusion-only model for fitting solid diffusivities to GITT or pulse data.

The model solves x-averaged spherical particle diffusion in each modelled electrode, with the surface flux set by the applied current, and computes the cell voltage from the electrode open-circuit potentials evaluated at the particle surface stoichiometries, minus an ohmic drop through a single lumped "Ohmic resistance [Ohm]" parameter. There are no reaction kinetics (Butler-Volmer), no electrolyte dynamics, and no thermal effects; all parameters are constant except the open-circuit potentials.

The "working electrode" option selects the cell configuration, following the usual pybamm half-cell idiom:

  • "both" (default): full cell. Both electrodes are modelled and the voltage is the difference of their open-circuit potentials minus the ohmic drop. A positive (discharge) current delithiates the negative electrode and lithiates the positive electrode.

  • "positive": half-cell against a lithium-metal counter electrode, following the pybamm half-cell convention. Only the working electrode is modelled (the counter electrode contributes no overpotential) and the voltage is its open-circuit potential minus the ohmic drop. A positive (discharge) current lithiates the working electrode. As in pybamm, anode-material half cells are also expressed with "positive" — rename the anode’s parameters to the positive convention first.

This is a fitting model intended for extracting solid-phase diffusivities (and the lumped ohmic resistance) from GITT or pulse-relaxation measurements — it is not a general-purpose simulation model. Each modelled electrode is parameterised with the standard pybamm full-cell parameter names (thickness, active material volume fraction, particle radius, diffusivity, OCP, maximum and initial concentrations) plus the current function, electrode cross-sectional area, initial temperature, and "Ohmic resistance [Ohm]".

Parameters

optionsdict, optional

Model options. "working electrode" may be "both" (default) or "positive" and selects the cell configuration as described above. Any remaining options are forwarded to the pybamm battery-model options for parameter bookkeeping; the governing equations of this model are fixed (diffusion-only), so options that select submodels have no effect on the physics.

namestr, optional

Name of the model. Default is "GITT model".

Extends: BaseModel

See also: GITTModel — field-level documentation.

property default_geometry

Returns a dictionary of the default geometry for the model, which is empty by default.

property default_spatial_methods

Returns a dictionary of the default spatial methods for the model, which is empty by default.

property default_submesh_types

Returns a dictionary of the default submesh types for the model, which is empty by default.

property default_var_pts

Returns a dictionary of the default variable points for the model, which is empty by default.

classmethod from_config(data: dict) GITTModel

Create a GITTModel from a config dict.

Parameters

datadict

Config dict as produced by to_config().

Returns

GITTModel

classmethod from_schema(schema)

Construct from a validated ionworks_schema.models.GITTModel.

to_config() dict

Serialise this model to a JSON-serialisable config dict.

Returns

dict

Config with "type" and, when any were supplied at construction, "options" (including "working electrode" exactly as given).

class ionworkspipeline.data_fits.models.MSMRHalfCellModel(electrode, options=None)

A class for the MSMR half-cell model of the open-circuit potential (OCP).

Parameters

electrodestr

The electrode to use for the model.

optionsdict, optional
A dictionary of options to pass to the model. The options include:
  • capacity function

    The capacity function to use for the model. Default is None.

  • species format

    The species format to use for the model. Can be “Qj” for capacity or “Xj” for mole fraction. Default is “Qj”.

  • direction

    The direction to use for the model. Can be None, “delithiation” or “lithiation”. Default is None.

  • particle phases

    How many particle phases are present in the electrode. Can be “1” (default) or “2” for composite electrodes with Primary and Secondary phases.

For a composite electrode (particle phases = "2") the lower excess that shifts q(U) may be given either as a per-phase split (Primary/Secondary: {Electrode} electrode lower excess capacity [A.h], summed) when it is known from another source, or as a single electrode-level {Electrode} electrode lower excess capacity [A.h] when it is not. The fit itself cannot resolve the split, so a composite fit uses the aggregate. No per-phase upper excess is read.

Extends: ConfigMixin

See also: MSMRHalfCellModel — field-level documentation.

build(parameter_values, data, voltage_limits=None, project=False)

Build the model.

Parameters

parameter_valuespybamm.ParameterValues

The parameter values to use for the model.

datadict

The data to use for the model.

voltage_limitstuple, optional

The voltage range over which to evaluate the variables returned by the solve_full method. Default is None, in which case the full range of the data is used.

projectbool, optional

Whether the fit projects the Xj onto the simplex; passed through to default_capacity_function() to disable sum-normalization for projected phases. Default is False.

default_capacity_function(electrode, parameter_values, species_format='Qj', direction=None, differential=False, project=False)

Get the default capacity function for the model. Returns ionworkspipeline.data_fits.objectives.get_q_half_cell_msmr.

Parameters

electrodestr

The electrode to use for the model.

parameter_valuespybamm.ParameterValues

The parameter values to use for the model.

species_formatstr, optional

The species format to use for the model. Default is “Qj”.

directionstr, optional

The direction to use for the model. Default is None.

differentialbool, optional

Whether to return the differential capacity function. Default is False.

projectbool, optional

Whether the fit projects the Xj onto the simplex. When True, the theta expression skips its sum-normalization for any phase whose Xj are all fit parameters (the projection owns sum(Xj) = 1, so a broken projection must fail loudly rather than be silently repaired). Default is False.

classmethod from_config(data: dict) MSMRHalfCellModel

Create an MSMRHalfCellModel from a config dict.

Parameters

datadict

Config dict as produced by to_config().

Returns

MSMRHalfCellModel

classmethod from_schema(schema)

Construct from a validated ionworks_schema.models.MSMRHalfCellModel.

Overrides the generic ConfigMixin.from_schema so the typed options bag is flattened via to_config (wire keys such as "species format") rather than model_dump (which would emit the python field name species_format and be rejected by the runtime).

solve(inputs, calculate_dQdU=False, calculate_dUdQ=False)

Solve the model at the given inputs.

Parameters

inputsdict

The inputs to use to evaluate the OCP.

calculate_dQdUbool, optional

Whether to calculate the differential capacity [Ah/V]. Default is False.

calculate_dUdQbool, optional

Whether to calculate the differential voltage [V/Ah]. Default is False.

Returns

dict

The outputs of the model. Should include “Capacity [A.h]”, “Differential capacity [Ah/V]”, “Differential voltage [V/Ah]”.

solve_full(inputs)

Solve the model over the voltage range specified by the voltage_limits option in the build method.

Parameters

inputsdict

The inputs to use to evaluate the OCP.

Returns

dict

The outputs of the model (“Full voltage [V]”, “Full capacity [A.h]”, “Full differential capacity [Ah/V]”, “Full differential voltage [V/Ah]”).

to_config() dict

Serialise this model to a JSON-serialisable config dict.

Returns

dict

Config with "type", "electrode", and optionally "options" (only serialisable string/numeric values; callables are omitted).

class ionworkspipeline.data_fits.models.MSMRFullCellModel(negative_electrode_model, positive_electrode_model, options=None)

A class for the MSMR full-cell model of the open-circuit potential (OCP).

Parameters

negative_electrode_modelMSMRHalfCellModel

The model for the negative electrode.

positive_electrode_modelMSMRHalfCellModel

The model for the positive electrode.

Extends: ConfigMixin

See also: MSMRFullCellModel — field-level documentation.

build(parameter_values, data, negative_voltage_limits, positive_voltage_limits, project=False)

Build the model.

Parameters

parameter_valuespybamm.ParameterValues

The parameter values to use for the model.

datadict

The data to use for the model.

negative_voltage_limitstuple

The voltage range over which to evaluate the negative electrode model.

positive_voltage_limitstuple

The voltage range over which to evaluate the positive electrode model.

projectbool, optional

Whether the fit projects the Xj onto the simplex; passed through to each electrode model’s build. Default is False.

classmethod from_config(data: dict) MSMRFullCellModel

Create an MSMRFullCellModel from a config dict.

Parameters

datadict

Config dict as produced by to_config().

Returns

MSMRFullCellModel

solve(inputs)

Solve the model at the given inputs.

Parameters

inputsdict

The inputs to use to evaluate the OCP.

Returns

dict

The outputs of the model. Should include “Capacity [A.h]” and “Differential voltage [V/Ah]”.

to_config() dict

Serialise this model to a JSON-serialisable config dict.

Returns

dict

Config with "type", "negative_electrode_model", and "positive_electrode_model".

class ionworkspipeline.data_fits.models.LumpedSPMR(options=None, name='Lumped Single Particle Model with Resistance')

Lumped Single Particle Model with Resistance

Parameters

optionsdict
Dictionary of options to override default options. Options are:
  • thermal: str, thermal model to use. Can be “isothermal” or “lumped”.

  • surface_temperature: str, surface temperature model to use. Can be “ambient” or “lumped”.

  • working_electrode: str, working electrode to use. Only “both” (full cell) is supported.

namestr, optional

The name of the model. Default is “Lumped Single Particle Model with Resistance”.

Extends: BaseModel

See also: LumpedSPMR — field-level documentation.

property default_geometry

Returns a dictionary of the default geometry for the model, which is empty by default.

property default_spatial_methods

Returns a dictionary of the default spatial methods for the model, which is empty by default.

property default_submesh_types

Returns a dictionary of the default submesh types for the model, which is empty by default.

property default_var_pts

Returns a dictionary of the default variable points for the model, which is empty by default.

classmethod from_schema(schema)

Construct from a validated ionworks_schema.models.LumpedSPMR.

static get_initial_state(initial_value, parameter_values, tol=1e-06)

Get the initial state of the model.

Parameters

initial_valuefloat

The initial value of the state.

parameter_valuesdict

The parameter values.

tolfloat, optional

The tolerance for the initial state.

Returns

tuple

The initial state of the model (x, y).

static get_stoichiometry_limits(parameter_values)

Get the stoichiometry limits from the electrode SOH solver.

Parameters

parameter_valuespybamm.ParameterValues

The parameter values. Must include “Negative electrode capacity [A.h]”, “Positive electrode capacity [A.h]”, and “Cyclable lithium capacity [A.h]”.

Returns

tuple

(x_0, x_100, y_100, y_0) stoichiometry limits.

static plot_voltage_components(solution, ax=None, show_plot=True, split_by_electrode=False, **kwargs_fill)

Plot voltage components from a solution.

Parameters

solutionpybamm.Solution

Solution to plot

axmatplotlib.axes.Axes, optional

Axes to plot on

show_plotbool, optional

Whether to show the plot

split_by_electrodebool, optional

Whether to show the overpotentials for the negative and positive electrodes separately. Default is False.

**kwargs_filldict, optional

Keyword arguments for fill_between

static set_initial_state(initial_value, parameter_values, tol=1e-06, inplace=True, inputs=None)

Set the initial state of the model.

Parameters

initial_valuefloat

The initial value of the state.

parameter_valuesdict

The parameter values.

tolfloat, optional

The tolerance for the initial state.

inplacebool, optional

Whether to set the initial state in place or return a new parameter values object.

inputsdict, optional

Optional inputs dictionary (unused, for API compatibility).

class ionworkspipeline.data_fits.models.LumpedSPMeR(options=None, name='Lumped Single Particle Model with Electrolyte and Resistance')

Lumped Single Particle Model with Resistance and Electrolyte concentration overpotential

Parameters

optionsdict
Dictionary of options to override default options. Options are:
  • thermal: str, thermal model to use. Can be “isothermal” or “lumped”.

  • surface_temperature: str, surface temperature model to use. Can be “ambient” or “lumped”.

  • working_electrode: str, working electrode to use. Only “both” (full cell) is supported.

namestr, optional

The name of the model. Default is “Lumped Single Particle Model with Electrolyte and Resistance”.

Extends: LumpedSPMR

See also: LumpedSPMeR — field-level documentation.

class ionworkspipeline.data_fits.models.SingleElectrodeLumpedSPMR(options=None)

Lumped single-electrode (half-cell) Single Particle Model with Resistance

Parameters

optionsdict

Dictionary of options to override default options. Options are:

  • thermal: “isothermal” or “lumped”

  • surface temperature: “ambient” or “lumped”

  • rc pairs: str, number of RC pairs to include in the model. Must be a non-negative integer as a string (e.g., “0”, “1”, “2”, “5”, etc.). Default is “0”.

  • parameter_dependencies: dict, optional. Specifies which variables each parameter depends on. Keys must be in [“tau”, “R_rc”, “C_rc”]. Values are tuples containing any combination of (“soc”, “temperature”). Empty tuple means the parameter is constant (pybamm.Parameter). Default is all dependencies for backward compatibility.

    Example:

    # No dependencies - all parameters are constants
    {"parameter_dependencies": {
        "tau": (),
        "R_rc": (),
        "C_rc": ()
    }}
    
    # Partial dependencies - tau depends only on SOC
    {"parameter_dependencies": {
        "tau": ("soc",),
        "R_rc": ("temperature",),
        "C_rc": ("soc", "temperature")
    }}
    

Notes

The model uses array parameters for RC pairs. Parameters should be specified as:

  • R_rc [Ohm]: list of resistance values for each RC pair

  • C_rc [F]: list of capacitance values for each RC pair

For example, with 2 RC pairs:

parameter_values = pybamm.ParameterValues({
    "R_rc [Ohm]": [0.01, 0.005],
    "C_rc [F]": [100, 200],
    ...
})

PyBaMM automatically converts array parameters to indexed format:

{"R_rc [Ohm]": [0.01, 0.005]} becomes {"R_rc (0) [Ohm]": 0.01, "R_rc (1) [Ohm]": 0.005}

Extends: BaseModel

See also: SingleElectrodeLumpedSPMR — field-level documentation.

static custom_set_initial_state(initial_value, parameter_values, inplace=False, **kwargs)

Custom set_initial_state for SingleElectrodeLumpedSPMR.

Converts a voltage string (e.g. “4.2 V”) or SOC float into the "Initial SOC" parameter that the lumped SPMR model expects.

Parameters

initial_valuestr or float

Either a voltage string like "4.2 V" or a numeric SOC (0–1).

parameter_valuespybamm.ParameterValues

The parameter values to update.

inplacebool, optional

If False (default), return a copy with the updated SOC.

**kwargs

Additional arguments (e.g. direction, inputs) forwarded by Simulation.set_initial_state; accepted but not used.

property default_geometry

Returns a dictionary of the default geometry for the model, which is empty by default.

property default_spatial_methods

Returns a dictionary of the default spatial methods for the model, which is empty by default.

property default_submesh_types

Returns a dictionary of the default submesh types for the model, which is empty by default.

property default_var_pts

Returns a dictionary of the default variable points for the model, which is empty by default.

classmethod from_schema(schema)

Construct from a validated ionworks_schema.models.SingleElectrodeLumpedSPMR.

static get_initial_soc_from_voltage(V_init, parameter_values, solver=None)

Calculate initial SOC from target OCP voltage using an algebraic PyBaMM model.

This method numerically inverts the open-circuit voltage (OCP) function to find the SOC that corresponds to a given voltage. It only considers the OCP (with entropic-change temperature correction), not overpotential or ohmic resistance terms.

Parameters

V_initfloat

Target open-circuit voltage [V]

parameter_valuesdict or pybamm.ParameterValues

Dictionary of parameter values needed to evaluate the OCP function. Must include: - “Open-circuit voltage [V]”: OCP function - “Open-circuit voltage entropic change [V.K-1]”: entropic coefficient - “Initial temperature [K]”: temperature for OCP evaluation - “Reference temperature [K]”: reference temperature - “Lower voltage cut-off [V]”: minimum voltage (for initial guess) - “Upper voltage cut-off [V]”: maximum voltage (for initial guess)

solverpybamm.Solver, optional

Solver to use for the algebraic equation. Default is AlgebraicSolver()

Returns

float

Initial SOC value that produces the target OCP voltage

Examples

>>> param_values = {
...     "Open-circuit voltage [V]": ocp_pos,
...     "Open-circuit voltage entropic change [V.K-1]": 0,
...     "Initial temperature [K]": 298.15,
...     "Reference temperature [K]": 298.15,
...     "Lower voltage cut-off [V]": 3.0,
...     "Upper voltage cut-off [V]": 4.2,
... }
>>> soc = SingleElectrodeLumpedSPMR.get_initial_soc_from_voltage(
...     3.8, param_values
... )
>>> 0 < soc < 1
True
static plot_voltage_components(solution, ax=None, show_plot=True, split_rc_pairs=False, **kwargs_fill)

Plot voltage components from a solution.

Parameters

solutionpybamm.Solution

Solution to plot

axmatplotlib.axes.Axes, optional

Axes to plot on

show_plotbool, optional

Whether to show the plot

split_rc_pairsbool, optional

Whether to show the RC pairs separately. Default is False.

**kwargs_filldict, optional

Keyword arguments for fill_between

class ionworkspipeline.data_fits.models.ECM(options=None)

Equivalent Circuit Model

Parameters

optionsdict

Dictionary of options to override default options. Options are:

  • thermal: str, thermal model to use. Can be “isothermal”, “lumped”, or “two-state”. Default is “isothermal”.

  • rc pairs: str, number of RC pairs to include in the model. Must be a non-negative integer as a string (e.g., “0”, “1”, “2”, “5”, etc.). Default is “0”.

  • capacity: str, degradation model for cell capacity. Either “constant” (default, capacity fixed at “Nominal cell capacity [A.h]”) or “function” (capacity is a user-supplied function of the degradation inputs below). When “function”, the parameter “Capacity [A.h]” must be supplied as such a function; pass a constant function such as lambda *args: 5.0 for no fade.

  • resistance scale: str, degradation model for resistance growth. Either “constant” (default, resistances unchanged) or “function” (all resistances R0 and R_rc are multiplied by a dimensionless user-supplied factor). When “function”, the parameter “Resistance scale” must be supplied as a function of the degradation inputs below; pass lambda *args: 1.0 for no growth. Capacitances C_rc are not scaled, so scaling an RC-pair resistance also lengthens its time constant tau = R_rc * C_rc by the same factor (a grown polarization resistance relaxes more slowly).

    A degradation function receives two positional arguments, (Q_throughput, time), and uses whatever subset it needs:

    # capacity that fades with throughput and calendar time
    def capacity(Q_throughput, time):
        return 5.0 - k_cyc * Q_throughput - k_cal * time
    

    Q_throughput is “Capacity throughput [A.h]” (the running integral of absolute current int |I| dt in A.h) and time is elapsed time in seconds. Both are monotonic accumulators of the past trajectory, so a function of them is inherently history-dependent and (for a monotonic function) irreversible – the right shape for degradation. Oscillating states such as SOC or voltage are deliberately not exposed, because an algebraic function of them would swing up and down every cycle rather than accumulate. Only “Capacity throughput [A.h]” requires an extra integrated state; time is a symbol the model already carries. A future accumulated-stress input can be appended as a further positional argument without breaking functions written today.

    When either “capacity” or “resistance scale” is “function”, the model integrates the extra “Capacity throughput [A.h]” state, which starts at 0. When both are “constant” (the default) no extra state is added and the model is identical to a non-degrading ECM.

    For the common “X% per full equivalent cycle” case, assign the ready-made helpers linear_capacity_loss / linear_resistance_increase (see their docstrings) to the “Capacity [A.h]” / “Resistance scale” parameters instead of writing the function by hand.

  • butler-volmer: str, either “false” (default) or “true”. When “true”, the series overpotential gains a symmetric Butler-Volmer charge-transfer term eta_ct = (2*R*T/F) * asinh(I / (2*i0)), so the terminal voltage becomes V = OCV - I*R0 - eta_ct - sum(RC pair voltages). Here i0 is the “Exchange current [A]” parameter, by default a function of state of charge (configurable via the parameter_dependencies key “i0”). The asinh is linear in current at low current (small-signal resistance R*T / (F*i0)) and logarithmic (Tafel) at high current, so a single SOC-dependent exchange current captures the rate-dependent overpotential that a linear R0 cannot. The term is exposed as the “Charge-transfer overpotential [V]” variable. The “resistance scale” degradation factor applies only to R0 and R_rc, not to the Butler-Volmer term.

  • parameter_dependencies: dict, optional. Specifies which variables each parameter depends on. Keys must be in [“OCV”, “R0”, “R_rc”, “C_rc”, “i0”] (“i0” only takes effect when the “butler-volmer” option is “true”). Values are tuples containing any combination of (“soc”, “current”, “temperature”). Empty tuple means the parameter is constant (pybamm.Parameter). Default is all dependencies for backward compatibility, except “i0” which defaults to (“soc”,) — its current dependence is the asinh itself, so a current-dependent exchange current would double-count kinetics.

    Supplying this dict replaces the defaults, so omitting one of “OCV”/”R0”/”R_rc”/”C_rc” makes that parameter constant. “i0” is the exception: omitting it still gives (“soc”,), so that an existing config written before this option existed does not silently flatten the charge-transfer overpotential to a constant. Pass “i0”: () explicitly for a constant exchange current.

    Example:

    # No dependencies - all parameters are constants
    {"parameter_dependencies": {
        "OCV": (),
        "R0": (),
        "R_rc": (),
        "C_rc": ()
    }}
    
    # Partial dependencies - OCV depends only on SOC
    {"parameter_dependencies": {
        "OCV": ("soc",),
        "R0": ("soc", "temperature"),
        "R_rc": ("soc", "temperature"),
        "C_rc": ("soc", "temperature")
    }}
    

Notes

The ECM model uses array parameters for RC pairs. Parameters should be specified as:

  • R_rc [Ohm]: list of resistance values for each RC pair

  • C_rc [F]: list of capacitance values for each RC pair

For example, with 3 RC pairs:

parameter_values = pybamm.ParameterValues({
    "R_rc [Ohm]": [0.02, 0.002, 0.001],
    "C_rc [F]": [1, 10, 100],
    ...
})

PyBaMM automatically converts array parameters to indexed format:

{"R_rc [Ohm]": [0.02, 0.002]} becomes {"R_rc (0) [Ohm]": 0.02, "R_rc (1) [Ohm]": 0.002}

Extends: BaseModel

See also: ECM — field-level documentation.

static custom_set_initial_state(initial_value, parameter_values, inplace=False, **kwargs)

Custom set_initial_state for ECM.

Converts a voltage string (e.g. “4.2 V”) or SOC float into the "Initial SOC" parameter that the ECM model expects.

Parameters

initial_valuestr or float

Either a voltage string like "4.2 V" or a numeric SOC (0–1).

parameter_valuespybamm.ParameterValues

The parameter values to update.

inplacebool, optional

If False (default), return a copy with the updated SOC.

**kwargs

Additional arguments (e.g. direction, inputs) forwarded by Simulation.set_initial_state; accepted but not used.

classmethod from_schema(schema)

Construct from a validated ionworks_schema.models.ECM.

static get_initial_soc_from_voltage(V_init, parameter_values, solver=None)

Calculate initial SOC from target OCV voltage using an algebraic model.

Parameters

V_initfloat

Target open-circuit voltage [V]

parameter_valuesdict or pybamm.ParameterValues

Must include "Open-circuit voltage [V]" and voltage cut-offs.

solverpybamm.Solver, optional

Defaults to pybamm.AlgebraicSolver().

Returns

float

Initial SOC that produces the target OCV.

Submodules