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:
BaseModelSee 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
GITTModelfrom a config dict.Parameters¶
- datadict
Config dict as produced by
to_config().
Returns¶
- classmethod from_schema(schema)¶
Construct from a validated
ionworks_schema.models.GITTModel.
- 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 shiftsq(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:
ConfigMixinSee also:
MSMRHalfCellModel— field-level documentation.- build(parameter_values, data, voltage_limits=None, project=False)¶
Build the model.
Parameters¶
- parameter_values
pybamm.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.
- parameter_values
- 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_values
pybamm.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
MSMRHalfCellModelfrom a config dict.Parameters¶
- datadict
Config dict as produced by
to_config().
Returns¶
- classmethod from_schema(schema)¶
Construct from a validated
ionworks_schema.models.MSMRHalfCellModel.Overrides the generic
ConfigMixin.from_schemaso the typed options bag is flattened viato_config(wire keys such as"species format") rather thanmodel_dump(which would emit the python field namespecies_formatand 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]”).
- 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_model
MSMRHalfCellModel The model for the negative electrode.
- positive_electrode_model
MSMRHalfCellModel The model for the positive electrode.
Extends:
ConfigMixinSee also:
MSMRFullCellModel— field-level documentation.- build(parameter_values, data, negative_voltage_limits, positive_voltage_limits, project=False)¶
Build the model.
Parameters¶
- parameter_values
pybamm.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.
- parameter_values
- classmethod from_config(data: dict) MSMRFullCellModel¶
Create an
MSMRFullCellModelfrom a config dict.Parameters¶
- datadict
Config dict as produced by
to_config().
Returns¶
- negative_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:
BaseModelSee 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:
LumpedSPMRSee 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:
BaseModelSee 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.
**kwargsAdditional arguments (e.g.
direction,inputs) forwarded bySimulation.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.0for 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.0for 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_throughputis “Capacity throughput [A.h]” (the running integral of absolute currentint |I| dtin A.h) andtimeis 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 becomesV = OCV - I*R0 - eta_ct - sum(RC pair voltages). Herei0is 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 resistanceR*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:
BaseModelSee 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.
**kwargsAdditional arguments (e.g.
direction,inputs) forwarded bySimulation.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.