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 0x7f7b73e99900>

  • 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([[50.]]))#

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 0x7f7b73e99900>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
model_post_init(context: Any, /) None#

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self – The BaseModel instance.

  • context – The context.

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 0x7f7b73e99900>

  • 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)] = 50.0#

Exponential approach rate. Units: 1/V

Constraints:
  • ge = 0.0

  • func = <function _encode_ndarray at 0x7f7b73e99900>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
model_post_init(context: Any, /) None#

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self – The BaseModel instance.

  • context – The context.

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 0x7f7b73e99900>

  • json_schema_input_type = PydanticUndefined

  • return_type = PydanticUndefined

  • when_used = json-unless-none

Validated by:
property amp_hour: ndarray#

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

An open circuit voltage that is dependent on state of charge and 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:
Validators:

field ocv_ent: SOCInterpolatedHealth [Optional]#

Entropic OCV to determine temperature dependence. Units: V/C

Validated by:
field ocv_ref: SOCInterpolatedHealth [Required]#

Reference OCV at specified temperature. Units V

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 0x7f7b73e99900>

  • 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#

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.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 0x7f7b73e99900>

  • 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 0x7f7b73e99900>

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

model_post_init(context: Any, /) None#

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self – The BaseModel instance.

  • context – The context.

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:

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 0x7f7b73e99900>

  • 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 0x7f7b73e99900>

  • 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 0x7f7b73e99900>

  • 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)#

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 – Initial value of hysteresis, corresponding to h[0]

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

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

  • dt – Length of time interval

  • i0 – Initial current

  • alpha – Slope of current profile during time interval

Returns:

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

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

Returns not very realistic R0 relationship to SOC

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

Returns not very realistic RC element relationships to SOC