Equivalent Circuit Models (moirae.models.ecm)#

Models that describe the state of health and transient state of an Equivalent Circuit Model

class moirae.models.ecm.EquivalentCircuitModel(current_behavior: Literal['constant', 'linear'] = 'constant')#

Bases: CellModel

Equivalent Circuit Model (ECM) dynamics of a battery

The only option for how to implement the battery is whether we assume the current varies linearly between the previous and current step, or whether it is assumed to be constant.

Parameters:

current_behavior – How the current is assumed to vary between timesteps.

calculate_terminal_voltage(new_inputs: ECMInput, transient_state: ECMTransientVector, asoh: ECMASOH) ECMMeasurement#

Compute expected output (terminal voltage, etc.) of the cell.

Parameters:
  • new_inputs – Inputs at the current time step

  • transient_state – Current transient state

  • asoh – Health parameters of the cell

Returns:

Estimates for all measurable outputs of a cell

current_behavior: str#

How it is assumed the current varies between timesteps

update_transient_state(previous_inputs: ECMInput, new_inputs: ECMInput, transient_state: ECMTransientVector, asoh: ECMASOH) ECMTransientVector#

Update the transient state of a chemical cell

Parameters:
  • previous_inputs – Inputs at the last time step

  • new_inputs – Inputs at the current time step

  • transient_state – Current transient state

  • asoh – Health parameters of the cell

Returns:

A new transient state

Health Parameters (moirae.models.ecm.advancedSOH)#

Definition of the state of health

pydantic model moirae.models.ecm.advancedSOH.ECMASOH#

Bases: HealthVariable

State of Health for an equivalent circuit model

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
Validators:

field c0: Capacitance | None = None#

Series Capacitance (C0)

Validated by:
field ce: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] = 1.0#

Coulombic efficiency (CE)

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
field h0: HysteresisParameters = HysteresisParameters(updatable=set(), base_values=array([[0.]]), soc_pinpoints=None, interpolation_style='linear', gamma=array([[0.]]))#

Hysteresis component

Validated by:
field ocv: OpenCircuitVoltage [Required]#

Open Circuit Voltage (OCV)

Validated by:
field q_t: MaxTheoreticalCapacity [Required]#

Maximum theoretical discharge capacity (Qt).

Validated by:
field r0: Resistance [Required]#

Series Resistance (R0)

Validated by:
field rc_elements: Tuple[RCComponent, ...] [Optional]#

Tuple of RC components

Validated by:
get_theoretical_energy(soc_limits: Tuple[float, float] = (0.0, 1.0), temperature: float | None = None) float | ndarray#

Function that computes the theoretical energy of the cell in Wh.

Computes cell energy by integrating Open-Circuit Voltage (OCV) over the supplied state of charge (SOC) ranges. Assumes no energy loss, such as from the resistive or hysteresis elements.

Parameters:
  • soc_limits – minimum and maximum SOC limit to be used in the computation of the energy; defaults to (0, 1)

  • temperature – value of temperature (in °C) to be used in the calculation of energy; defaults to None

Returns:

value(s) of maximum theoretical energy as a 2D array of shape (asoh_batch_size, 1)

classmethod provide_template(has_C0: bool, num_RC: int, qt: float = 10.0, CE: float = 1.0, OCV: float | ndarray | None = None, R0: float | ndarray = 0.05, C0: float | ndarray | None = None, H0: float | ndarray = 0.05, RC: List[Tuple[ndarray, ...]] | None = None) ECMASOH#

Create an ECM using a simple template

Parameters:
  • has_C0 – Whether circuit includes a serial capacitor

  • num_RC – How many RC elements are within the circuit

  • qt – Maximum theoretical capacity. (Units: Amp-hr)

  • CE – Coulombic efficiency

  • OCV – Open circuit voltage at equally-spaced SOCs. (Units: V)

  • R0 – Series resistance. (Units: Ohm)

  • C0 – Series capacitance (Units: Farad)

  • H0 – Hysteresis value at equally-spaced SOCs (Units: V)

  • RC – List of tuples of (resistance, capacitance) (Units: V)

Returns:

A set of parameters describing the entire circuit

Components (moirae.models.ecm.components)#

Models for the components of circuits

pydantic model moirae.models.ecm.components.Capacitance#

Bases: SOCInterpolatedHealth

Defines the series capacitance component of the ECM

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
Validators:

field base_values: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] [Required]#

Values of series capacitance at specified SOCs. Units: F

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
pydantic model moirae.models.ecm.components.EntropicOCV#

Bases: SOCInterpolatedHealth

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
Validators:

field base_values: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] = 0#

Values of entropic OCV term at specified SOCs. Units: V/°C

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
pydantic model moirae.models.ecm.components.HysteresisParameters#

Bases: SOCInterpolatedHealth

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
Validators:

field base_values: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] [Required]#

Values of maximum hysteresis at specified SOCs. Units: V

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
field gamma: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] = 0.0#

Exponential approach rate. Units: 1/V

Constraints:
  • ge = 0.0

  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
pydantic model moirae.models.ecm.components.MaxTheoreticalCapacity#

Bases: HealthVariable

Defines maximum theoretical discharge capacity of a cell

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
Validators:

field base_values: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] [Required]#

Maximum theoretical discharge capacity of a cell. Units: Amp-hour

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
property amp_hour: float#

Returns capacity in Amp-hour, as it was initialized.

property value: float#

Returns capacity in Amp-second

pydantic model moirae.models.ecm.components.OpenCircuitVoltage#

Bases: HealthVariable

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
Validators:

field ocv_ent: EntropicOCV [Required]#

Entropic OCV to determine temperature dependence

Validated by:
field ocv_ref: ReferenceOCV [Required]#

Reference OCV at specified temperature

Validated by:
get_value(soc: float | List | ndarray, temp: float | List | ndarray | None = None) float | ndarray#

Returns values of OCV at given SOC(s) and temperature(s).

pydantic model moirae.models.ecm.components.RCComponent#

Bases: HealthVariable

Defines an RC component of the ECM

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
Validators:

field c: Capacitance [Required]#

Capacitive element of RC component

Validated by:
field r: Resistance [Required]#

Resistive element of RC component

Validated by:
get_value(soc: float | List | ndarray, temp: float | List | ndarray | None = None) List[float | ndarray]#

Returns values of resistance and capacitance at given SOC and temperature.

time_constant(soc: float | List | ndarray, temp: float | List | ndarray | None = None) float | ndarray#
pydantic model moirae.models.ecm.components.ReferenceOCV#

Bases: SOCInterpolatedHealth

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
Validators:

field base_values: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] [Required]#

Values of reference OCV at specified SOCs. Units: V

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
field reference_temperature: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] = 25#

Reference temperature for OCV0. Units: °C

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
pydantic model moirae.models.ecm.components.Resistance#

Bases: SOCInterpolatedHealth

Defines the series resistance component of an ECM.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
Validators:

field base_values: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] [Required]#

Values of series resistance at specified SOCs. Units: Ohm

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
field reference_temperature: float | None = 25#

Reference temperature for internal parameters. Units: °C

Validated by:
field temperature_dependence_factor: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] = 0#

Factor determining dependence of R0 with temperature. Units: 1/°C

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
get_value(soc: float | List | ndarray, temp: float | List | ndarray | None = None) float | ndarray#

Computes value of series resistance at a given SOC and temperature.

Inputs and Outputs (moirae.models.ecm.ins_and_outs)#

pydantic model moirae.models.ecm.ins_outs.ECMInput#

Bases: InputQuantities

Control of a battery based on the feed current, temperature

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
field temperature: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] | None = None#

Temperature reading(s). Units: °C

pydantic model moirae.models.ecm.ins_outs.ECMMeasurement#

Bases: OutputQuantities

Controls the outputs of the ECM.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:

Transient State (moirae.models.ecm.transient)#

pydantic model moirae.models.ecm.transient.ECMTransientVector#

Bases: GeneralContainer

Description of the state of charge of an ECM and all components

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
field hyst: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] = 0.0#

Hysteresis voltage. Units: V

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

field i_rc: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] = ()#

Currents through RC components. Units: Amp

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

field q0: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] | None = None#

Charge in the series capacitor. Units: Coulomb

field soc: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] = 0.0#

SOC

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

classmethod from_asoh(asoh: ECMASOH)#

Make a transient vector based on the design of a circuit captured in the state of health

Parameters:

asoh – State of health for an ECM

Returns:

An appropriate transient state

classmethod provide_template(has_C0: bool, num_RC: int, soc: float = 0.0, q0: float = 0.0, i_rc: float | ndarray | None = None, hysteresis: float = 0.0) ECMTransientVector#

Function to help provide ECMTransientVector template copies based on ECM description. Allows for initialization of specific variables if needed.

Parameters:
  • has_C0 – Whether circuit includes a serial capacitor

  • num_RC – How many RC elements are within the circuit

  • soc – State of charge between 0 and 1

  • q0 – Charge on the serial capacity (units: C)

  • i_rc – Current over each of the rc_elements (units: A)

  • hysteresis – Hysteresis value (units: V)

Returns:

A set of parameters describing the current charge state

Utilities (moirae.models.ecm.utils)#

pydantic model moirae.models.ecm.utils.SOCInterpolatedHealth#

Bases: HealthVariable

Defines basic functionality for HealthVariables that need interpolation between SOC pinpoints

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Config:
  • arbitrary_types_allowed: bool = True

Fields:
Validators:

field base_values: _encode_ndarray, return_type=PydanticUndefined, when_used=json-unless-none)] = 0#

Values at specified SOCs

Constraints:
  • func = <function _encode_ndarray at 0x7f9155b8b250>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
field interpolation_style: Literal['linear', 'nearest', 'nearest-up', 'zero', 'slinear', 'quadratic', 'cubic', 'previous', 'next'] = 'linear'#

Type of interpolation to perform

Validated by:
field soc_pinpoints: ndarray | None = None#

SOC pinpoints for interpolation.

Validated by:
get_value(soc: Number | List | ndarray) ndarray#

Computes value(s) at given SOC(s).

This function always returns a 3D array, of shape (internal_batch_size, soc_batch_size, soc_dim), where internal_batch_size is the batch size of the underlying health variable, soc_batch_size is the batch size of the SOC array, and soc_dim is the dimensionality of the SOC. The SOC must be passed as either: 1. a 2D array of shape (soc_batch_size, soc_dim) 2. a 1D array of shape (soc_dim,), in which case we will consider the soc_batch_size to be equal to 1 3. a 0D array (that is, a numer), in which case both soc_batch_size and soc_dim are equal to 1.

Parameters:
  • soc – Values at which to compute the property

  • broadcast_batch – flag to determine whether to broadcast as much as possible. If True, it will try to match

  • True (SOC batches with internal batches and remove superfluous dimensions; defaults to)

Returns:

Interpolated values

iter_parameters(updatable_only: bool = True, recurse: bool = True) Iterator[tuple[str, ndarray]]#

Iterate over all parameters which are treated as updatable

Parameters:
  • updatable_only – Only iterate over variables which are updatable

  • recurse – Whether to gather parameters from attributes which are also HealthVariable classes.

Yields:

Tuple of names and parameter values as numpy arrays. The name of parameters from attributes which are HealthVariable will start will be “<name of attribute in this class>.<name of attribute in submodel>”

moirae.models.ecm.utils.hysteresis_solver_const_sign(h0: float | ndarray, M: float | ndarray, kappa: float | ndarray, dt: float | ndarray, i0: float | ndarray, alpha: float | ndarray) float#

Helper function to solve for hysteresis at time dt given initial conditions, parameters, and current and current slope. Assumes current does not change sign during time interval

Parameters:
  • h0 (float) – Initial value of hysteresis, corresponding to h[0]

  • M (float) – Asymptotic value of hysteresis at present condition (the value h[t] should approach)

  • kappa (float) – Constant representing the product of gamma (SOC-based rate at which hysteresis approaches M), Coulombic efficienty, and 1/Qt

  • dt (float) – Length of time interval

  • i0 (float) – Initial current

  • alpha – Slope of current profile during time interval

  • Outputs

  • -------

  • h_dt (float) – Hysteresis value at the end of the time interval

moirae.models.ecm.utils.realistic_fake_ocv(soc_vals: float | ndarray) ndarray#

Returns somewhat realistic OCV relationship to SOC