Docstrings
The docstrings of BatteryComponents: every exported name, and the parameter-set and structural-selection docstrings from the other pages.
Index
BatteryComponents.BattXBatteryComponents.CellViewBatteryComponents.CycleLifeBatteryComponents.CyclerStateBatteryComponents.DFNBatteryComponents.DPBatteryComponents.EDLCBatteryComponents.ESCBatteryComponents.EquivalentCircuitModelBatteryComponents.ExperimentPlanBatteryComponents.ExperimentResultBatteryComponents.ForcedAirCoolingBatteryComponents.HPPCPulseBatteryComponents.LookupTableBatteryComponents.LookupTableBatteryComponents.NDCBatteryComponents.PNGVBatteryComponents.PackThermalNetworkBatteryComponents.RCFitBatteryComponents.RCModelBatteryComponents.RandlesBatteryComponents.RintBatteryComponents.SPMBatteryComponents.SPMeBatteryComponents.TheveninBatteryComponents.TremblayDessaintBatteryComponents.ArrayBatteryPackBatteryComponents.ArrayHeatPortBatteryComponents.BattXCircuitBatteryComponents.BattXLawBatteryComponents.BatteryCellBatteryComponents.BatteryPackBatteryComponents.BijuFang2022BatteryComponents.BulkSurfaceCircuitBatteryComponents.BulkSurfaceECMBatteryComponents.CPEModeBatteryComponents.CPETailBatteryComponents.ChenRinconMora2006BatteryComponents.ChenRinconMoraECMBatteryComponents.CyclerBatteryComponents.CyclingCircuitBatteryComponents.DualPolarizationECMBatteryComponents.ECMBulkSurfaceBatteryComponents.ECMChargeBatteryComponents.ECMHealthBatteryComponents.ECMNDCNetworkBatteryComponents.ECMOCVDriftBatteryComponents.ECMOhmicBatteryComponents.ECMPolarizationBatteryComponents.ECMThermalMassBatteryComponents.EDLCParametersBatteryComponents.ESCCircuitBatteryComponents.ESCCurrentSignBatteryComponents.ESCHysteresisBatteryComponents.ESCPolarizationBatteryComponents.ESCTerminalBatteryComponents.EquivalentCircuitCellBatteryComponents.EquivalentCircuitParametersBatteryComponents.He2011LiMn2O4BatteryComponents.LCOBatteryComponents.LFPBatteryComponents.LFP2BatteryComponents.MaxwellPC2500BatteryComponents.NCABatteryComponents.NDCCircuitBatteryComponents.NMCBatteryComponents.NMC_LiMetalBatteryComponents.PNGVCircuitBatteryComponents.PNGVECMBatteryComponents.PackAmbientBatteryComponents.PackForcedAirBatteryComponents.PlettE2BatteryComponents.RandlesCapacitorBatteryComponents.RandlesCircuitBatteryComponents.RandlesTerminalBatteryComponents.RintCircuitBatteryComponents.RintECMBatteryComponents.SaftHighPower12AhBatteryComponents.SaftLiIon6AhBatteryComponents.TheveninCircuitBatteryComponents.TheveninECMBatteryComponents.Tian2020NCR18650BBatteryComponents.TremblayDessaint2009BatteryComponents.TremblayDessaintECMBatteryComponents.TremblayDessaintLawBatteryComponents.Vandeputte2023BatteryComponents.WarburgModeBatteryComponents.WarburgRemainderBatteryComponents.aluminum_current_collectorBatteryComponents.calibrate_rcBatteryComponents.capacity_cellBatteryComponents.capacity_packBatteryComponents.cell_viewsBatteryComponents.chargeBatteryComponents.charge_currentBatteryComponents.charge_powerBatteryComponents.copper_current_collectorBatteryComponents.currentBatteryComponents.default_boundsBatteryComponents.default_parametersBatteryComponents.dischargeBatteryComponents.discharge_currentBatteryComponents.discharge_powerBatteryComponents.experiment_resultsBatteryComponents.find_variablesBatteryComponents.gridvariablesBatteryComponents.hppc_pulsesBatteryComponents.linear_ocvBatteryComponents.linear_resistanceBatteryComponents.powerBatteryComponents.randles_impedanceBatteryComponents.rc_initial_guessBatteryComponents.rc_tablesBatteryComponents.restBatteryComponents.rint_resistanceBatteryComponents.rint_tablesBatteryComponents.table_lookupBatteryComponents.voltageBatteryComponents.SEI_degradation_default_paramsBatteryComponents.BatteryElectrodeSelectionBatteryComponents.BatteryModelFamilyBatteryComponents.BatteryParameterSetBatteryComponents.BatteryThermalModelBatteryComponents.ECMDegradationBatteryComponents.ECMTopologyBatteryComponents.RandlesDiffusionBatteryComponents.RandlesDoubleLayerBatteryComponents.SEIParameterSet
The ESC API comprises ESC, PlettE2, ESCCircuit, ESCCurrentSign, ESCHysteresis, ESCPolarization, and ESCTerminal.
The Randles API comprises Randles, Vandeputte2023 and randles_impedance, with the generated components listed in the Dyad component reference.
BatteryComponents
BatteryComponents.BattX — TypeBattX(; N = 5)The BattX coupled-circuit model of Biju and Fang [1]: an equivalent circuit that couples four sub-circuits — solid-phase diffusion, electrolyte diffusion, a lumped core/surface thermal network, and the terminal voltage law — to track the physics of a single particle model with electrolyte and thermal dynamics (SPMeT) while staying an ordinary-differential circuit. It is the only model here whose terminal voltage is driven by internal diffusion states rather than a (SOC, T) open-circuit-voltage curve.
N is the number of finite-volume nodes in the solid-diffusion chain (sub-circuit A, equation (1)); it is structural, exactly as Thevenin's RC order is. The published identification (BijuFang2022) uses N = 5 with its own "solid diffusion capacitance ratios" and "solid diffusion resistance ratios" (equation (20)); a different N needs matching-length ratios of its own.
V̇_s,1 = (V_s,2 - V_s,1)/(C_s,1 R_s,1) - I/C_s,1 (solid diffusion, eq. 1)
V̇_e,1 = (V_e,2 - V_e,1)/(C_e R_e) - I/C_e (electrolyte, eq. 2)
Ṫ_core = (Q + (T_surf - T_core)/R_core) / C_core (thermal, eq. 3a)
Ṫ_surf = ((T_core - T_surf)/R_core + (T_ref - T_surf)/R_surf) / C_surf (eq. 3b, plus q_left/q_right)
Q = I (U_s(SOC) - U_s(V_s,1)) + R_o,T I² (heat generation, eq. 4)
V = U_s(V_s,1) + U_e(V_e,1, V_e,3) - R_o,T I (terminal voltage, eq. 5)with U_s the piecewise solid-phase OCV (equation, Section 2, unnumbered), U_e the electrolyte voltage (equation (6)), and R_o,T the SoC- and Arrhenius-corrected series resistance (equations (7)-(9)). Current here is discharge-positive (as every model in this file is); the paper's I is charge-positive, so the sign of every I term above is flipped from the paper's own printing.
Thermal coupling. temperature = false (the default) fixes T_core = T_surf = T_ref at the cell's initial temperature — an isothermal cell, exactly as every other model's is. temperature = true gives BattX its own two-state core/surface network instead of the shared single lumped mass the other models use: T_cell (used everywhere else — the Arrhenius corrections, Q_gen, the pack thermal network) is T_core, since that is the temperature equations (7) and (9) use, and heatport_left/heatport_right touch the surface node T_surf through the cell's own R_surf, the paper's identified convective resistance. This is the natural reading of "the existing temperature = true path, the same way the other models do it": the external contract (the kwarg, the two heat ports, T_cell, Q_gen) is identical, and the two-state network is BattX's own extension of it, the way RCModel extends the shared cell with two capacitor states beyond what Rint has. R_surf is therefore an additional internal resistance to whatever a pack's own thermal network attaches beyond the port — physically the cell's own boundary layer, in series with any external cooling.
State of charge. The shared coulomb counter (SOC, driven by "nominal capacity") is what equations (7)-(8) mean by "SoC" — Section 4's identification says so directly ("SoC can be obtained via Coulomb counting"). It is not forced equal to the solid-diffusion chain's own charge-weighted average (Σ Cₛⱼ Vₛⱼ / Σ Cₛⱼ, exposed as the diagnostic SOC_solid), even though the two coincide to machine precision when the diffusion capacities are consistent with the nominal capacity — BijuFang2022's Table 1 C_s,1 and its own coulomb-counted capacity disagree by about 1%, and this preserves that disagreement rather than silently rescaling one to match the other.
Design decisions not dictated by the paper, each made explicitly rather than guessed: prescribed-health resistance_growth scales the series resistance of every other topology here but does not reach BattX's own R_o,T/R_s1,T — wiring it in would need a design choice the paper gives no guidance on (which of the two resistances, or both, and by how much); T_ref (the Arrhenius/convective reference "ambient" of equations (3b), (7) and (9), which the paper's own bench tests never distinguish from room temperature) is the cell's initial temperature, not a separately identified constant; and BattX is not added to the ECMTopology/EquivalentCircuitCell Dyad enum dispatcher, which assumes an externally supplied open-circuit-voltage input that BattX has no use for and would otherwise force onto every one of BattX's 30-odd parameters.
Circuit keys: "solid diffusion capacitance" (C_s,1), "solid diffusion resistance" (R_s,1), "solid diffusion capacitance ratios" (η, N entries), "solid diffusion resistance ratios" (σ, N - 1 entries), "electrolyte diffusion capacitance" (C_e), "electrolyte diffusion resistance" (R_e), "electrolyte voltage coefficients" (β, 2 entries), "solid open-circuit voltage coefficients" (α, 17 entries), "series resistance coefficients" (γ, 3 entries), "Arrhenius coefficients" (κ, 2 entries: κ₁ for R_o,T, κ₂ for R_s1,T), "core thermal capacitance", "core thermal resistance", "surface thermal capacitance" and "surface thermal resistance". Every scalar entry may also be a (SOC, T) callable or a LookupTable, as every other model's circuit elements can; the published fit uses only constants. η and σ are read once, as plain numbers — they fix the chain's discretization rather than vary with the operating point.
[1] Nikhil Biju and Huazhen Fang. "BattX: An Equivalent Circuit Model for Lithium-Ion Batteries Over Broad Current Ranges." arXiv:2211.05999 (2022). https://arxiv.org/abs/2211.05999
BatteryComponents.CellView — TypeCellViewA view of one cell's symbolic states and parameters in a shared array pack. Use cell_views to obtain views. Property access returns the (series, parallel) element of the pack array that holds the quantity, at the quantity's grid index where the array has grid axes, for use in parameter updates and solution indexing; it creates no subsystem.
BatteryComponents.CycleLife — TypeCycleLife(variable, results)Marker for plot(sol, CycleLife(circuit.SOH, results)): the value of variable (usually the state of health) at the end of every cycle against the cycle number. results are the ExperimentResults of the solution, from experiment_results.
BatteryComponents.CyclerState — TypeThe mutable state of a Cycler that is shared with its event affects: the protocol (steps) and a log of the steps that ended (log: time, step index, exit reason), which experiment_results turns into results. The cycler appends to the log, so empty!(state.log) before solving the same problem a second time.
BatteryComponents.DFN — TypeDFN(chemistry; options...)
DFN()
The Doyle-Fuller-Newman (`DFN`) model is an advanced pseudo-2D battery model. It accurately represents electrochemical processes within a lithium-ion battery, including diffusion, reactions, and concentration gradients in both electrodes. This model offers high-fidelity simulations, enabling analysis and optimization of battery performance under various operating conditions.BatteryComponents.DP — TypeDP()The dual-polarization (DP) model of [1]: Thevenin with two RC pairs, the first standing for electrochemical polarization (R_1, C_1, the fast pair Rpa/Cpa of [1]) and the second for concentration polarization (R_2, C_2, the slow Rpc/Cpc). Splitting the two is what [1] adds to the first-order model, and it is the most accurate of the five models compared there.
It is the same topology as Thevenin(2) and has the same variables; the separate type exists because the literature names it separately and because a parameter set identified per model (He2011LiMn2O4) has its own entry for it.
Parameter set keys: those of Thevenin, with two entries per RC vector.
[1] Hongwen He, Rui Xiong and Jinxin Fan. "Evaluation of Lithium-Ion Battery Equivalent Circuit Models for State of Charge Estimation by an Experimental Approach." Energies 4, no. 4 (2011): 582-598. https://doi.org/10.3390/en4040582
BatteryComponents.EDLC — TypeEDLC()The electric double-layer capacitor (supercapacitor) cell: an ideal capacitance C in series with an equivalent series resistance R_0, which is Rint with the open-circuit voltage of a capacitor rather than of a faradaic cell,
V = q / C - I * R_0, dq/dt = -IIts state of charge is the stored charge against the charge at the rated voltage, SOC = q / (C * V_rated), which makes the open-circuit voltage the straight line OCV = SOC * V_rated and the usable energy C (V₁² - V₂²) / 2 rather than a plateau. That is the whole physical difference from Rint, and it is why the family exists as a type: a double-layer capacitor is specified by a capacitance, an equivalent series resistance and a voltage rating, not by an ampere-hour capacity and a measured open-circuit-voltage curve.
Only the immediate branch of [1] is modelled: no voltage-dependent capacitance, no delayed or long-term branch, and no leakage. Over a single charge or discharge of a few minutes the immediate branch is what carries the response, and [2] finds one such R-C pair enough to match a measured charge and discharge; over hours the missing branches and the leakage resistance are what the model gets wrong.
Parameter set keys: "capacitance", "rated voltage", "series resistance" — see EDLCParameters, which builds a set from exactly those three numbers. The "nominal capacity" of the "overall" section is derived, not read: it is C * V_rated / 3600 A⋅h, the value that makes the shared coulomb counter integrate dq/dt = -I.
The "capacitance" and "rated voltage" entries have to be constants. A (SOC, T) callable is accepted for "series resistance", so a temperature-dependent series resistance costs nothing, but a temperature-dependent capacitance would move the charge the state of charge is counted against, and is rejected rather than quietly integrated wrong.
[1] Luis Zubieta and Richard Bonert. "Characterization of double-layer capacitors for power electronics applications." IEEE Transactions on Industry Applications 36, no. 1 (2000): 199-205. https://doi.org/10.1109/28.821816
[2] Richard L. Spyker and R. M. Nelms. "Classical equivalent circuit parameters for a double-layer capacitor." IEEE Transactions on Aerospace and Electronic Systems 36, no. 3 (2000): 829-836. https://doi.org/10.1109/7.869502
BatteryComponents.ESC — TypeESC(; n = 1)
ESC(n)Plett's enhanced self-correcting equivalent circuit with n ≥ 0 RC branches, continuous hysteresis and event-driven current-direction memory. Positive current means discharge. The hysteresis voltage loss h follows
dh/dt = -abs(eta * I * gamma / (3600 * Q)) * (h - M * sign(I))
V = OCV + M0 * s - h - sum(R_j * i_Rj) - R0 * Ih is the negative of Plett's signed hysteresis voltage (Notes 02, pp. 2–11–2–15). It stays in [-M, M] for constant nonnegative M and an initial value in that interval. With a state-dependent M, h relaxes toward M(SOC, T) * sign(I) at the rate above rather than scaling instantly with M. Both h and the discrete last-current sign s retain memory at rest. eta is the charge efficiency for negative current and one for discharge. Q is available capacity in Ah, and time is in seconds.
Circuit keys are the Thevenin resistance/capacitance keys, "hysteresis magnitude" [M, V], "instantaneous hysteresis magnitude" [M0, V], and "hysteresis rate" [gamma, dimensionless]. Optional keys are "initial hysteresis voltage" [V, zero], "initial polarization current" [A, a length-n vector, zero], "initial current sign" [-1, 0 or 1, zero], and "current sign threshold" [A, 1e-8]. s is the current's direction whenever abs(I) >= threshold and holds its value inside the band. Continuous events locate the outward crossings of either threshold; a discrete event applies the same update after a step in which the current jumped across the band inside another event, such as a cycler step. The initial sign is that of the initialized current, or "initial current sign" inside the band. The threshold affects s only, not the continuous dynamics.
M, M0 and gamma, whether constants or every value of a LookupTable, must be nonnegative, and the magnitude of the initial hysteresis voltage may not exceed M at the initial state of charge and temperature. These checks run when the cell or pack is built; values replaced later through parameter_values, remake or setp are not checked.
In a parallel group, M0 > 0 makes the current split non-unique. A cell's terminal voltage jumps by 2 M0 as its current crosses zero, so whenever the group voltage lies within M0 of OCV - h - sum(R_j * i_Rj), several splits satisfy the circuit, and M0 * s feeds a circulating current between the cells. When the group current passes through zero without a jump, as a drive cycle with regenerative phases does, roundoff decides which cell switches first, and the cells' currents, h and SOC diverge irreproducibly. This is a property of the published model rather than of the sign implementation; a smoothed or sampled sign has the same non-uniqueness. BatteryPack warns when parallel > 1 and M0 is not identically zero. Series strings and single cells under an imposed current, and M0 = 0, are unaffected; a cell or string held at a voltage within M0 of OCV - h - sum(R_j * i_Rj) has the same ambiguity in its own current. A current that jumps through zero inside an event, as at a CyclingCircuit step, keeps identical parallel cells equal.
Each RC state is a branch current, di_Rj/dt = (I-i_Rj)/(R_j*C_j), so changing resistance maps preserve the state convention in Plett's equations. Thermal output includes resistor dissipation and charge inefficiency, not a calibrated hysteresis heat law. The default parameter set is PlettE2 at 25 °C for n = 1; other orders require an explicit chemistry.
Source: Gregory L. Plett, ECE4710/5710 Notes 02, pp. 2–11–2–15 (unnumbered equations), https://mocha-java.uccs.edu/ECE5710/ECE5710-Notes02.pdf.
BatteryComponents.EquivalentCircuitModel — TypeEquivalent circuit models (ECMs) describe a cell as a small electrical network — a voltage source in series with resistances and RC pairs — rather than resolving the electrochemistry the way DFN, SPMe and SPM do. They carry no spatial discretization and no concentrations, so they are orders of magnitude cheaper and are what battery management systems are usually built on, at the cost of parameters that have to be identified per cell and hold only over the conditions they were identified at.
The subtypes are Rint, Thevenin, DP, PNGV and RCModel, the five models compared in [1], and EDLC, which is the same arithmetic for a double-layer capacitor rather than a faradaic cell. They are used with BatteryCell, BatteryPack and CyclingCircuit exactly as the electrochemical models are, with an ECM parameter set as the chemistry (ChenRinconMora2006, He2011LiMn2O4, SaftLiIon6Ah, MaxwellPC2500).
TremblayDessaint supplies a Shepherd-derived empirical voltage law with filtered-current polarization and an exponential zone, parameterized by TremblayDessaint2009.
Randles is the impedance-oriented Randles circuit, with finite-length Warburg diffusion ladders and constant-phase-element variants realized over stated frequency bands, parameterized by Vandeputte2023.
[1] Hongwen He, Rui Xiong and Jinxin Fan. "Evaluation of Lithium-Ion Battery Equivalent Circuit Models for State of Charge Estimation by an Experimental Approach." Energies 4, no. 4 (2011): 582-598. https://doi.org/10.3390/en4040582
BatteryComponents.ExperimentPlan — TypeOne step of a cycling protocol as planned: the operating mode, the input (a setpoint or hold), the maximum time and the step-specific bounds. Built by charge, discharge, voltage, power and rest.
BatteryComponents.ExperimentResult — TypeOne experiment of a cycling protocol as it ran, from experiment_results: the ExperimentPlan's fields, plus the exit_reason that ended it ("Maximum voltage reached", "Stop time reached", ...), the indices idxs and the times tspan it covers in the solution, and the cycle it belongs to.
BatteryComponents.ForcedAirCooling — TypeForcedAirCooling(; flow_axis = :none, area = 0.032, case_thickness = 0.001,
case_conductivity = 15.0, fan_flow = 0.07 / 12, natural_flow = 0.001,
flow_area = 0.0011, air_density = 1.16, air_heat_capacity = 1009.0,
air_mass = 0.0, h_reference = 30.0, velocity_reference = 5.0,
velocity_exponent = 0.8, h_natural = 4.0, T_set = 308.15, hysteresis = 2.0)The hardware of a PackForcedAir boundary: a module case, a stream of cooling air, and the thermostat that switches the fan. flow_axis selects the geometry; the remaining fields are parameters of the compiled system. The shipped values are those of the Saft 6 A⋅h lithium-ion module data set of ADVISOR 2003 (NREL, ESS_LI7_temp.m), whose single-node thermal model this boundary reimplements, so they describe one module in a parallel-flow pack rather than a pack of any particular size; scale area, fan_flow and flow_area to the pack being modelled.
flow_axisis:nonefor one mean-air node,:seriesfor one node per series row, or:parallelfor one node per parallel column. Flow enters at index 1 and leaves at the largest index.areaandair_massare totals, divided equally among the nodes;fan_flowandnatural_flowpass through every node in the chain.area[m²] is the case surface the air passes over;case_thickness[m] andcase_conductivity[W/m/K] give the conduction resistancet / (k A)of the massless case wall.fan_flow[kg/s] is the air mass flow with the fan on, andflow_area[m²] the cross-section it passes through, so the air velocity isfan_flow / (air_density * flow_area).natural_flow[kg/s] is the exchange of the air around the module with the surroundings while the fan is off; the source floors its air flow at this value.h_reference * (v / velocity_reference)^velocity_exponentis the forced-convection film coefficient [W/m²/K] at velocityv, andh_naturalthe coefficient with the fan off. The defaults are the correlation ADVISOR fits to Incropera and DeWitt,h = 30 (v / 5)^0.8with a natural-convection floor of 4.air_mass[kg] is the total mass of air the boundary holds. The realistic value for a cooling passage is a fraction of a gram, whose time constant is milliseconds against the minutes of the cells, so the default0.0treats the air as quasi-steady, which is also the form of the source; a positive value makes the air temperature a state.T_set[K] switches the fan on when the sensed temperature rises through it, and the fan goes off again when the temperature falls throughT_set - hysteresis. The source has no hysteresis, but a relay with none chatters as soon as the fan's cooling exceeds the heating and the integration stalls at the setpoint, sohysteresismust be positive and defaults to 2 K.
BatteryComponents.HPPCPulse — TypeHPPCPulseOne current pulse of a pulse test together with the rest on either side of it, as hppc_pulses cuts it from a recorded test. The fields are
time,current,voltage: the samples [s, A, V] from the last rest sample before the pulse to the last rest sample before the next current step (or the end of the record), with the current discharge-positive as everywhere in the package;pulse_end: the index, into those vectors, of the last sample on the pulse;indices: the range of the samples in the record the pulse was cut from;temperature[K]: the temperature of the test;soc_before,soc_after: the state of charge at the rest before and after the pulse,NaNwherehppc_pulseswas given no way to know it;rest_before[s]: how long the cell had been at rest when the pulse started, since the previous current step or the start of the record.
So voltage[1] is the rest voltage the pulse starts from, voltage[pulse_end] the last voltage under load, and voltage[end] the voltage at the end of the rest that follows.
BatteryComponents.LookupTable — TypeLookupTable(axes::Tuple, values)
LookupTable(x, y, values)A table of values on the rectangular grid spanned by axes, a tuple of one or two strictly increasing breakpoint vectors, interpolated linearly along each axis and held at the nearest edge outside the grid. values has one dimension per axis: a vector over the breakpoints of a one-dimensional table, and for a two-dimensional table a matrix with one row per breakpoint of the first axis and one column per breakpoint of the second, which is what LookupTable(x, y, values) builds. An axis with a single breakpoint is constant along it.
A LookupTable is data rather than an expression. In a model it is the value of a nonnumeric parameter, read by the pure function table_lookup, so it is stored in the problem's MTKParameters: remake or setp replaces it on a compiled problem without rebuilding or recompiling anything, and the generated code never contains it. It is also callable, table(x) or table(x, y), to evaluate it outside a model; a two-dimensional table with a single breakpoint on its first axis may be called with the second coordinate alone.
Between breakpoints the value is linear along each axis (bilinear for two axes), the piecewise-linear lookup of Modelica.Blocks.Tables with its default smoothness = LinearSegments. Outside the grid it is held at the edge, Modelica's HoldLastPoint extrapolation. The interpolant is continuous but its slope is not, so the Jacobian of a model using it jumps at every breakpoint.
using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D
decay = LookupTable(([0.0, 1.0, 2.0],), [1.0, 3.0, 2.0])
@parameters k::typeof(decay) = decay
@variables x(t) = 0.5
@mtkcompile sys = System([D(x) ~ -table_lookup(k, x)], t)
prob = ODEProblem(sys, [], (0.0, 1.0))
faster = remake(prob; p = [sys.k => LookupTable(([0.0, 1.0, 2.0],), [2.0, 6.0, 4.0])])BatteryComponents.LookupTable — MethodLookupTable(; soc = nothing, temperature = nothing, values)A LookupTable over the state of charge and the cell temperature, the form an EquivalentCircuitParameters set takes a measured grid in: as any "circuit" entry, read at (SOC, T), and, with only a temperature axis, as the "nominal capacity" or "coulombic efficiency" of the "overall" section, read at T. It is the data format of the Rint tables of ADVISOR [1], whose battery files give Voc(SOC, T), R_dis(SOC, T), R_chg(SOC, T), C(T) and η(T) on exactly such a grid, and which interpolates them piecewise-linearly as a LookupTable does.
soc and temperature are the strictly increasing breakpoints of the two axes; temperature may carry a Unitful unit (u"°C" is converted) and is stored in kelvin. Either axis may be left out, in which case the table is constant along it and values is a vector over the axis that is given; with both axes values is a matrix with one row per state of charge and one column per temperature. The result is always the two-dimensional table with the state of charge as its first axis, a single breakpoint standing in for an axis left out, so LookupTable(soc, temperature, values) builds the same table from plain numbers. The values are plain numbers in the unit the entry expects — SI for a circuit element, A⋅h for the capacity — exactly as any other callable entry.
A table entry becomes a nonnumeric parameter of the cell, named after the constant the entry would otherwise be with a _table suffix: U_oc_table, R_0_table (or R_0_discharge_table and R_0_charge_table), R_k_table and C_k_table for the RC branches, nominal_capacity_tableₒcell and η_coulombic_tableₒcell. The pack reads one shared table for all of its cells, so a table leaves the equation count unchanged, and the table can be replaced on a compiled problem with remake or setp, as long as the replacement has the same number of axes and, in the "overall" section, stays constant along the state of charge.
R_dis = LookupTable(; soc = [0.0, 0.5, 1.0], temperature = [0.0, 25.0]u"°C",
values = [0.0419 0.0720; 0.0143 0.0050; 0.0162 0.0057]) # Ω; rows: SOC, columns: T
Q = LookupTable(; temperature = [0.0, 25.0, 41.0]u"°C", values = [5.943, 7.035, 7.405]) # A⋅h
R_dis(0.25, 285.65) # bilinear
Q(298.15) # a temperature-only table takes one argument[1] Valerie H. Johnson. "Battery performance models in ADVISOR." Journal of Power Sources 110, no. 2 (2002): 321-329. https://doi.org/10.1016/S0378-7753(02)00194-5
BatteryComponents.NDC — TypeNDC()The nonlinear double-capacitor (NDC) model of Tian, Fang, Chen and Wang (2020) [1]: the bulk/surface charge-transport network of RCModel (R_e-C_b in parallel with R_c-C_c, the same equations as He2011LiMn2O4's circuit), driving a nonlinear terminal voltage source h(V_s) instead of a resistively-weighted blend of the two capacitor voltages, in series with one R_1-C_1 polarization branch and the ohmic resistance R_0,
i_b + i_c = I, V_b - i_b R_e = V_s - i_c R_c,
dV_b/dt = -i_b / C_b, dV_s/dt = -i_c / C_c,
dV_1/dt = -V_1 / (R_1 C_1) + I / C_1,
V = h(V_s) - V_1 - I R_0V_b and V_s are not voltages but dimensionless charge fractions: [1] normalizes them so that a fully charged network has V_b = V_s = 1 and a fully depleted one has V_b = V_s = 0, the same scale as SOC. h(·) is exactly the "open-circuit voltage" of the parameter set, since [1] identifies it as the cell's SoC-OCV curve and then reuses it at the network's own V_s state rather than at the coulomb-counted SOC; away from equilibrium V_s and SOC can differ (the network's stored charge redistributes between C_b and C_c on its own time constants), which is what gives the model the rate-capacity and charge-recovery effects the linear double-capacitor already had, while h(·) adds the nonlinear terminal voltage the linear one could not represent. SOC itself stays the ordinary coulomb count of every other model here (see build_ecm_cell); NDC does not add a third state-of-charge convention alongside RCModel's coulomb and capacitor options, since V_s is not a voltage that a curve has to be inverted through.
At rest (I = 0), V_b = V_s is the only fixed point, V_1 = 0, and V = h(V_s); [1] constructs h(·) so that this is exactly the identified SoC-OCV curve, OCV = h(SOC). V_b(0) = V_s(0) = SOC_initial and V_1(0) = 0 (Section III-B, p. 5: "V_s(0) ... can be accessed from SoC(0) when the battery is initially relaxed").
Parameter set keys: "open-circuit voltage" (the nonlinear map h), "end resistance", "capacitor resistance", "bulk capacitance", "surface capacitance" (the shared bulk/surface network, using RCModel's key names), "polarization resistance", "polarization capacitance" (the R_1-C_1 branch) and "series resistance" (or the "discharge resistance"/"charge resistance" pair; R_0). See Tian2020NCR18650B.
[1] Ning Tian, Huazhen Fang, Jian Chen and Yebin Wang. "Nonlinear Double-Capacitor Model for Rechargeable Batteries: Modeling, Identification and Validation." IEEE Transactions on Control Systems Technology (2020). https://doi.org/10.1109/TCST.2020.2976036 (arXiv:1906.04150; Mitsubishi Electric Research Laboratories TR2020-035).
BatteryComponents.PNGV — TypePNGV()The PNGV capacitance model of [1] and [2]: a first-order Thevenin whose open-circuit voltage is a constant U_oc, with the drift of the open-circuit voltage carried by an extra series capacitor C_ocv = 1 / U'_oc instead,
V = U_oc - U_d - U_1 - I * R_0, dU_d/dt = I / C_ocvU_d is the accumulated open-circuit-voltage change, so the model is a local linearization of the OCV curve about the state of charge it was identified at, and "open-circuit voltage" must therefore be a constant rather than a function of the state of charge — a full OCV(SOC) alongside U_d would count the same drift twice. It is named after the Partnership for a New Generation of Vehicles, whose test manual [1] defines the pulse test it is identified from.
Parameter set keys: "open-circuit voltage" (constant), "series resistance", "OCV capacitance", "polarization resistance" and "polarization capacitance" (one entry each).
[1] PNGV Battery Test Manual, Revision 3. DOE/ID-10597, Idaho National Engineering and Environmental Laboratory, February 2001. https://avt.inl.gov/sites/default/files/pdf/battery/pngvmanualrev3b.pdf
[2] Valerie H. Johnson. "Battery performance models in ADVISOR." Journal of Power Sources 110, no. 2 (2002): 321-329. https://doi.org/10.1016/S0378-7753(02)00194-5
BatteryComponents.PackThermalNetwork — TypePackThermalNetwork(; conductance = 1.0, conductance_lateral = conductance,
coolant_conductance = 1.0, coolant_conductance_lateral = 0.0)A lumped thermal network over the cells of a BatteryPack, in which every cell exchanges heat with its geometric neighbours and only the cells on the outside of the block reach the coolant. A cell in the middle of a pack is surrounded by other heat sources and has no face on the outside, so it runs hotter than a cell at the edge.
Each cell already carries its own heat capacity and heat generation, so the network supplies only the couplings, in the standard lumped-module form
C_i dT_i/dt = Q_i + Σ_j G_ij (T_j - T_i) + G_coolant,i (T_coolant - T_i)which is the model of Pozzi et al. ([doi:10.1109/TCST.2020.2995308] (https://doi.org/10.1109/TCST.2020.2995308)), who note that any arrangement of the cells is described thermally by the choice of the resistances alone. Abbas et al. resolve a module of 3 to 10 pouch cells this way and report the mechanism directly: heat accumulates in the middle of the module, "where the cells are less exposed to air compared to the external cells, since they are surrounded by insulation layers on both sides" (doi:10.3390/batteries10030098). Reniers and Howey give the other half of it — the middle cells "exchange heat conductively with two adjacent hot cells, while cells one and five benefit from some conductive cooling to the wall of the block" — and find that leaving the coupling out changes the predicted spread of cell capacities over 10000 cycles substantially (doi:10.1016/j.apenergy.2023.120774).
The cells sit on the pack's own series × parallel grid. The parallel axis is the direction the cells are stacked face to face, so its coupling runs through the cell's own heatport_left/heatport_right and its conductance is conductance. The series axis is the direction the rows sit side by side, coupled through the casing, holders and busbars with the conductance conductance_lateral; that path reaches both ends of the cell, half of it to each. coolant_conductance and coolant_conductance_lateral are the conductances from one exposed face of a boundary cell to the coolant, per axis; a cell in the interior of the grid has no exposed face and so no direct path to the coolant at all. All four are in W/K, they are parameters of the compiled system, and they are pairwise conductances, not conductivities.
The network couples the faces of the cells, which for a cell with one lumped temperature — every equivalent circuit, and an electrochemical model built with temperature = :lumped — are both at that temperature. An electrochemical model built with temperature = true resolves the temperature through the thickness of the cell and carries one temperature at each face, and the network then acts on those. Along the parallel axis the right face of each cell exchanges heat with the left face of the next through conductance, and the two outer faces of every stack reach the coolant through coolant_conductance. Along the series axis each face exchanges heat with the same face of the neighbouring rows through half of conductance_lateral, and an exposed face with the coolant through half of coolant_conductance_lateral, so the two faces of a cell together see the whole lateral path. Heat crosses a cell only by the cell's own conduction, which the network leaves unchanged; as the cell's thermal conductivity grows, its faces approach one temperature and the network approaches its lumped form.
The defaults are order-of-magnitude values from the literature, not a parameterization of any particular pack, and a quantitative study should replace them. conductance = 1.0 W/K is the reciprocal of the 1 K/W default inter-cell thermal resistance of Simscape Battery, whose quoted range is 0.01–10 K/W for pouch cells and 1–100 K/W for cylindrical ones ([Simscape Battery, "Model Heat Exchange Between Cells"] (https://www.mathworks.com/help/simscape-battery/ug/inter-cell-thermal-path-workflow.html)). coolant_conductance = 1.0 W/K is of the order of the measured surface cooling coefficients of pouch cells — 1.00 W/K for a 5 Ah Kokam K50, 2.99–7.33 W/K for larger cells (Russell et al., [doi:10.1016/j.ohx.2022.e00257] (https://doi.org/10.1016/j.ohx.2022.e00257)) — and is also the pre-existing heat_transfer_coefficient default of CyclingCircuit, so a pack of one cell is unchanged. coolant_conductance_lateral = 0.0 cools the pack only through the two ends of each stack; raise it to model a pack that also sits on a cold plate.
A pack built with a network exposes heatport_coolant in place of the per-row heatport_left/heatport_right, so the coolant can be an ambient, a cold plate or a fluid loop; CyclingCircuit holds it at T_ambient, or cools it with a PackForcedAir boundary when given cooling.
With coolant_axis = :none (the default), BatteryPack exposes a scalar coolant port. With coolant_axis = :series or :parallel, it exposes an (N, 1) port for an axis of length N > 1. Entry k supplies the exposed faces of slice k, and reports their summed heat flow into the cells. Internal cell-to-cell heat flow is excluded from that sum. CyclingCircuit selects this geometry from cooling.flow_axis and connects the coolant port to the case nodes of the forced-air chain. The q_coolant field has shape (series, parallel) and reports heat entering each cell through its exposed coolant faces, for every node count.
@named circuit = CyclingCircuit(; model = Thevenin(), series = 4, parallel = 3,
protocol = charge(1C), thermal_network = PackThermalNetwork())Limitations
Thermal coupling follows geometry while current sharing follows the circuit, and the two are in general separate specifications: mapping the same series × parallel circuit onto the same physical block in two different ways changes the current and ageing distribution measurably (He et al., [doi:10.1038/s44172-024-00222-3] (https://doi.org/10.1038/s44172-024-00222-3)). This network takes the physical grid to be the pack's own series × parallel grid, which is the conventional assembly order but not the only one; an arbitrary permutation of cells onto grid positions is not expressible here, because it would destroy the banded structure the array equations rely on.
For a cell with a distributed temperature the lateral path enters only at the two faces. The casing and holders it stands for touch the edge of a cell along its whole thickness, so heat that the real path would deliver to the interior of the cell is delivered to its faces here; the difference is of the order of the temperature difference across a cell.
BatteryComponents.RCFit — TypeRCFitThe result of calibrating the RCModel to one pulse with calibrate_rc.
circuit: the five elements as the"terminal resistance","end resistance","capacitor resistance","bulk capacitance"and"surface capacitance"entries of anEquivalentCircuitParameterscircuit section;pngv: the same impedance as the"series resistance","OCV capacitance","polarization resistance"and"polarization capacitance"of thePNGVmodel, which has exactly the RC model's terminal behaviour and, unlike it, one set of elements for it (seecalibrate_rc);capacitance_ratio: theC_b / C_cthe elements were taken at, andratio_rangethe range of ratios for which elements with the calibrated impedance and the bulk branch the slower are all positive (by default the ratio is the range's geometric midpoint);soc,temperature: thesoc_beforeand the temperature [K] of the (first) pulse;rms_error,max_error: the root-mean-square and the largest voltage error [V] of the calibrated model over the pulse;retcode: the return code of the calibration's optimizer. MadNLP, DyadModelOptimizer's default, reports a least-squares minimum whose residual is not zero asInfeasible("search direction becoming too small") even where it has converged, so judge a fit byrms_error;inverse_problem,calibration: the DyadModelOptimizerInverseProblemthe pulse was calibrated as and itsCalibrationResult, for DyadModelOptimizer's own analysis and plotting (simulate,plot,convergenceplot).
BatteryComponents.RCModel — TypeRCModel(; soc = :coulomb)The RC (capacitance) model of [1] and [2], due to SAFT and shipped in ADVISOR: two capacitors in parallel branches — a very large bulk capacitor C_b behind the end resistance R_e, standing for the charge the cell stores chemically, and a small surface capacitor C_c behind the capacitor resistance R_c, standing for surface effects — with the terminal resistance R_t in series to the pins:
i_b + i_c = I, U_b - i_b R_e = U_c - i_c R_c,
dU_b/dt = -i_b / C_b, dU_c/dt = -i_c / C_c, V = U_b - i_b R_e - I * R_tThe cell's charge lives in U_b, not in an OCV curve, so "open-circuit voltage" is used only to set U_b and U_c at t = 0 (both equal the rest voltage at SOC_initialₒcell). By default (soc = :coulomb) the SOC variable is coulomb-counted for the stop conditions and the pack interface and is not what drives the terminal voltage, so the two can drift apart over a long simulation. Of the five models [2] compares, this one has the second-largest terminal-voltage error under a dynamic load (0.234 V mean), behind only the Rint model.
soc = :capacitor defines the state of charge from the capacitor voltages instead, the way [1] does (its equation 2): each capacitor voltage is read back through the open-circuit voltage curve, OCV(SOC_b, T) = U_b and OCV(SOC_c, T) = U_c, and the cell's state of charge is the capacitance-weighted mean
SOC = (C_b SOC_b + C_c SOC_c) / (C_b + C_c)which for a linear curve is the fraction of the charge the two capacitors hold over the curve. [1] fixes the weights at 20:1, the capacitance ratio of the Saft cell its model was written for (SaftHighPower12Ah, 82 kF against 4.074 kF); the weighting here reduces to that ratio for that cell and follows the capacitances for any other, where a fixed 20:1 would be arbitrary (He2011LiMn2O4 has a ratio near 2350). A rested cell has U_b = U_c = OCV(SOC, T), so this state of charge cannot drift from the terminal voltage, and a set whose capacitances and capacity disagree, as He2011LiMn2O4's do, shows the disagreement as a difference between the two definitions rather than hiding it.
The inversion is written as one implicit algebraic equation per capacitor, so no closed-form inverse is needed and the equation count of a pack stays independent of its size. It needs an "open-circuit voltage" that is a (SOC, T) callable and strictly increasing in the state of charge over [0, 1] at the initial temperature; the curve is sampled when the cell is built and a constant, or a curve held flat outside its window (linear_ocv with clamped = true over a sub-window), is rejected there rather than solved for a state of charge it does not determine. A capacitor voltage outside the curve's range over [0, 1] extrapolates the curve. "self-discharge current", "coulombic efficiency" and ECMDegradation.PrescribedHealth act on the coulomb counter, so they are rejected with this option rather than read and ignored. A temperature-dependent "nominal capacity" is accepted: the state of charge still comes from the capacitor voltages, and the capacity sets only the C-rate and the reported cell capacity.
Parameter set keys: "open-circuit voltage", "terminal resistance", "end resistance", "capacitor resistance", "bulk capacitance", "surface capacitance". See He2011LiMn2O4 and SaftHighPower12Ah.
[1] Valerie H. Johnson. "Battery performance models in ADVISOR." Journal of Power Sources 110, no. 2 (2002): 321-329. https://doi.org/10.1016/S0378-7753(02)00194-5
[2] Hongwen He, Rui Xiong and Jinxin Fan. "Evaluation of Lithium-Ion Battery Equivalent Circuit Models for State of Charge Estimation by an Experimental Approach." Energies 4, no. 4 (2011): 582-598. https://doi.org/10.3390/en4040582
BatteryComponents.Randles — TypeRandles(; diffusion = :transmissive, order = diffusion === :cpe ? 24 : 8,
double_layer = :capacitor, double_layer_order = double_layer === :cpe ? 16 : 0)The Randles impedance model of Vandeputte et al. [1] (Fig. 2, eq. (11)) in the time domain: an open-circuit voltage and a series resistance R_s in series with a double layer in parallel with the charge-transfer resistance R_ct and a diffusion element Z_d,
Z(s) = R_s + 1 / (Y_dl(s) + 1 / (R_ct + Z_d(s))), V = OCV(SOC, T) - R_s I - v_dlwith discharge-positive I. randles_impedance evaluates Z(jω) exactly. Every fractional or distributed element is a bounded finite-state realization, named below with its order and the band where it is accurate.
diffusion selects Z_d:
:transmissive: the finite-length WarburgR_d tanh(√(sτ_d))/√(sτ_d)(planar diffusion to a fixed-concentration boundary);:reflective: the finite-space WarburgR_d coth(√(sτ_d))/√(sτ_d)(a blocking boundary), which is capacitive,R_d/(sτ_d) + R_d/3, at low frequency;:cpe: a constant phase element1/(Q_d s^α_d),0 < α_d < 1. The semi-infinite Warburgσ√2/√(jω)of [1], eq. (9), isα_d = 1/2,Q_d = 1/(σ√2).
double_layer selects Y_dl: :capacitor for s C_dl, or :cpe for Q_dl s^α_dl.
Finite-length Warburg realization (order = N modes): the exact partial fractions of tanh z / z (logarithmic derivative of DLMF 4.36.2) and coth z / z (DLMF 4.36.3), z² = sτ_d, truncated after N Foster RC branches,
R_k = 2 R_d / λ_k², C_k = τ_d / (2 R_d), λ_k = (k - 1/2)π (transmissive), kπ (reflective)plus a static remainder resistor R_d - Σ R_k (transmissive) or R_d/3 - Σ R_k (reflective), the DC resistance of the truncated modes, and for :reflective the series capacitor τ_d / R_d. For 0 ≤ ω ≤ λ_N² / (8τ_d) its complex relative error |Z_N - Z| / |Z| is below 0.9%, its magnitude error below 0.6% and its phase error below 0.4°, for every N. That band edge is 2.8/τ_d (transmissive) or 4.9/τ_d (reflective) at N = 2, and 69/τ_d or 79/τ_d at N = 8. Above it the missing modes make the element resistive instead of decaying as ω^(-1/2).
CPE realization (order = M branches for the diffusion CPE, double_layer_order for the double layer): the series RC network of Valsa, Dvořák and Friedl [2] (Fig. 9, eqs. (24)–(26)), with element values from the midpoint rule, in ln x, of the Stieltjes representation s^(-α) = sin(πα)/π ∫₀^∞ x^(-α)/(s + x) dx (DLMF 5.12.3 with 5.5.3) over the band 2π [f_low, f_high], h = ln(f_high/f_low)/M, x_k = 2π f_low e^(h(k - 1/2)):
R_k = h sin(πα) / (π Q x_k^α), C_k = 1 / (R_k x_k)
C_low = π Q (1 - α) (2π f_low)^(α-1) / sin(πα), R_high = sin(πα) / (π α Q (2π f_high)^α)C_low and R_high replace the relaxations below and above the band, as [2]'s correcting elements do. Every element is positive, so Re Z ≥ 0 at every frequency. A CPE needs at least two branches per decade of [f_low, f_high], which is checked when the cell is built. On [100 f_low, f_high/100] the complex relative error is then at most 1.2e-3, the magnitude error 1.02e-3 and the phase error 0.061°, for every α in (0, 1) (the error is symmetric under α ↔ 1 - α and largest near α = 0.3 and 0.7); on [10 f_low, f_high/10] the complex error is at most 1%. The error there is set by the two tail elements, not by the order. Outside the band the realization is a capacitor below f_low and a resistor above f_high.
States and limits. The double layer holds v_dl, the faradaic current is i_f = I - i_dl, and each capacitor and RC branch carries a voltage state, all zero at t = 0 except an optional initial double-layer voltage. SOC counts the terminal current, as in every EquivalentCircuitModel; the double-layer charge is not faradaic but is transient. The model is linear in the current about the open-circuit voltage, which is how [1] uses it (eq. (6): small excitation at constant SOC). The low-frequency capacitors of :reflective and :cpe store charge the way C_ocv of PNGV does: under a sustained current their voltage keeps growing and adds to the drop of an SOC-dependent open-circuit voltage.
Parameter set keys. "open-circuit voltage", "series resistance" [Ω] and "charge transfer resistance" [Ω]; "double-layer capacitance" [F] for :capacitor, with optional "initial double-layer voltage" [V, zero by default]; "double-layer CPE coefficient" [F⋅s^(α-1)], "double-layer CPE exponent" and "double-layer CPE band" [(f_low, f_high), Hz] for a CPE double layer; "diffusion resistance" [Ω] and "diffusion time constant" [s] for a finite-length Warburg; "diffusion CPE coefficient", "diffusion CPE exponent" and "diffusion CPE band" for a CPE. The bands and the initial voltage are constants; the other elements may be constants, LookupTables or (SOC, T) callables. Constant and tabulated elements are checked when the cell is built: resistances and capacitances positive (R_s nonnegative), exponents in (0, 1), 0 < f_low < f_high. ECMDegradation.PrescribedHealth scales R_s, R_ct and R_d by the resistance growth. No configuration has a default parameter set: Vandeputte2023 gives the published impedance and needs the open-circuit voltage and capacity, which the source does not, as keywords.
[1] Freja Vandeputte, Noël Hallemans, Jishnu Ayyangatu Kuzhiyil, Nessa Fereshteh Saniee, Widanalage Dhammika Widanage and John Lataire. "Frequency domain parametric estimation of fractional order impedance models for Li-ion batteries." arXiv:2305.15840 (2023). https://arxiv.org/abs/2305.15840
[2] Juraj Valsa, Petr Dvořák and Martin Friedl. "Network Model of the CPE." Radioengineering 20, no. 3 (2011): 619-626. https://www.radioeng.cz/fulltexts/2011/1103619_626.pdf
BatteryComponents.Rint — TypeRint()The internal-resistance (Rint) model: an open-circuit voltage in series with a single resistance, V = OCV(SOC, T) - I * R_0. It has no dynamics beyond the state of charge, so it reproduces the steady-state discharge curve and the instantaneous voltage step of a current pulse but none of the relaxation that follows. It is the least accurate of the five models [2] compares, with the largest terminal-voltage error under a dynamic load (0.394 V mean, against 0.043 V for the DP model).
Parameter set keys: "open-circuit voltage", "series resistance" (or the "discharge resistance" / "charge resistance" pair selected by the sign of the current; see EquivalentCircuitParameters).
[1] Valerie H. Johnson. "Battery performance models in ADVISOR." Journal of Power Sources 110, no. 2 (2002): 321-329. https://doi.org/10.1016/S0378-7753(02)00194-5
[2] Hongwen He, Rui Xiong and Jinxin Fan. "Evaluation of Lithium-Ion Battery Equivalent Circuit Models for State of Charge Estimation by an Experimental Approach." Energies 4, no. 4 (2011): 582-598. https://doi.org/10.3390/en4040582
BatteryComponents.SPM — TypeSPM(chemistry; options...)
SPM()
The Single-Particle Model (`SPM`) model is a simplified version of the `SPMe` model, commonly used by technical battery engineers for quick and computationally efficient simulations. It represents the battery as single particles in both electrodes without considering the electrolyte dynamics. While less detailed than the `DFN` or `SPMe` models, the `SPM` model is effective for initial assessments, rapid battery analysis, and large-scale pack simulations.BatteryComponents.SPMe — TypeSPMe(chemistry; options...)
SPMe()
The Single-Particle Model with electrolyte (`SPMe`) is a popular model to understand lithium-ion battery behavior. It simplifies the battery into a single particle for each electrode, considering electrolyte dynamics within the cell. This model allows for efficient simulations and provides valuable insights into cell-level behavior and degradation mechanisms.BatteryComponents.Thevenin — TypeThevenin(; n = 1)
Thevenin(n)The Thevenin model: Rint with n parallel RC pairs in series, which give the voltage relaxation a sum of n exponentials,
V = OCV(SOC, T) - Σₖ Uₖ - I * R_0, dUₖ/dt = -Uₖ / (Rₖ Cₖ) + I / Cₖn = 1 is the first-order model of [1]; n = 2 is the second-order model, which is also what DP is. Of the twelve lumped models [2] compares on two cells, it prefers the first-order RC model for a LiNMC cell and the first-order RC model with one-state hysteresis for a LiFePO₄ one. ESC provides dynamic hysteresis and instantaneous current-direction memory.
Parameter set keys: "open-circuit voltage", "series resistance", "polarization resistance" and "polarization capacitance" (a vector of n entries each).
[1] Hongwen He, Rui Xiong and Jinxin Fan. "Evaluation of Lithium-Ion Battery Equivalent Circuit Models for State of Charge Estimation by an Experimental Approach." Energies 4, no. 4 (2011): 582-598. https://doi.org/10.3390/en4040582
[2] Xiaosong Hu, Shengbo Li and Huei Peng. "A comparative study of equivalent circuit models for Li-ion batteries." Journal of Power Sources 198 (2012): 359-367. https://doi.org/10.1016/j.jpowsour.2011.10.013
BatteryComponents.TremblayDessaint — TypeTremblayDessaint(; battery_type = :lithium_ion)Shepherd-derived empirical dynamic model of Tremblay and Dessaint [1]. Supported battery_types are :lithium_ion, :lead_acid, :nimh and :nicd. Discharge current is positive, extracted capacity q = Q*(1-SOC) is in Ah, and time is in seconds:
dSOC/dt = -I/(3600Q), dI_filtered/dt = (I-I_filtered)/tau
OCV = E0 - Kq*Q*q/(Q-q) + exponential_voltage
V = OCV - R0*I - Ki*Q*I_filtered/denominatorThe discharge denominator is Q-q when I_filtered >= 0; charge uses q+0.1Q (abs(q)+0.1Q for nickel cells), following the MathWorks implementation [2]. Paper [1], equation (4), instead prints K*Q/(it-0.1Q); [2] specifies K*Q/(it+0.1Q). The printed form has a pole at it=0.1Q, or 90% SOC. With Table 1's Li-ion parameters and I=I_filtered=-2.3 A, it gives 178.187641 V at 89.99% SOC and -171.412348 V at 90.01% SOC. This model explicitly chooses [2]'s plus form to permit charging through that operating region; the singular form is not an option. Branch selection uses filtered current, so reversal does not switch the polarization coefficient until that state crosses zero.
Li-ion uses A*exp(-B*q) (equation (1)). The other chemistries use the state dx/dt = B*abs(I)*(A*u-x)/3600 (equation (2)), with u=1 for I<0 and zero otherwise. tau is a first-order time constant, 30 s in [1], section 3; it is not [2]'s time to 95% response. Kq [V/Ah] and Ki [ohm] have the same numerical value in the published fits but distinct dimensions.
The domain is 0 <= q < Q. The depletion pole q=Q is retained, without clipping; use the parameter set's SOC stop bounds in a CyclingCircuit. The no-load voltage saturation listed in [1], section 2.3.5, is outside this constitutive equation model. Initial SOC must be in (0,1]. Temperature dynamics, prescribed health, self-discharge, nonzero entropic coefficients and non-unit coulombic efficiency are unsupported. The reported heat is only R0*I^2; the empirical polarization law does not supply a thermodynamic heat model.
q is not bounded above by Q: coulomb counting can push SOC past one (q<0) under sustained charging. Li-ion's charge denominator q+0.1Q then has an undocumented pole at q=-0.1Q (110% SOC); nickel's abs(q)+0.1Q has none, since abs(q)+0.1Q>0 for every real q, so it stays finite through and past SOC=1. That is the only behavioral difference nickel makes above 100% SOC — within the documented 0 <= q < Q domain, abs(q)=q and the branches coincide.
Circuit keys are "constant voltage" [V], "series resistance" [ohm], "polarization voltage coefficient" [V/Ah], "polarization current coefficient" [ohm], "exponential amplitude" [V], "exponential inverse capacity" [Ah^-1], and "current filter time constant" [s], all constants. Optional "initial filtered current" [A] defaults to zero. Optional "initial exponential voltage" [V] defaults to A*exp(-B*Q*(1-SOC_initial)) for the three chemistries with memory — the exact solution of equation (2) for a cell discharged at rest from SOC=1, which reduces to A when SOC_initial=1. Li-ion's exponential is algebraic and does not accept that initial-state key. See TremblayDessaint2009.
[1] O. Tremblay and L.-A. Dessaint (2009), Experimental Validation of a Battery Dynamic Model for EV Applications, equations (1)–(5), Table 1. https://doi.org/10.3390/wevj3020289
[2] MathWorks, Battery block, R2025a, lithium-ion charge/discharge model. https://www.mathworks.com/help/releases/R2025a/sps/powersys/ref/battery.html
BatteryComponents.ArrayBatteryPack — MethodArrayBatteryPack(; name, family = BatteryModelFamily.EquivalentCircuit(),
topology = ECMTopology.Thevenin(), series = 1, parallel = 1, kwargs...)The Dyad interface to the shared array pack. family, topology, parameter_set, thermal, degradation, sei, sei_parameters and lam are structural enums. Electrochemical SEI/LAM selections specify electrodes, and sei_parameters names the published SEI parameter set (see SEI_degradation_default_params); ECM degradation selects no degradation or externally prescribed capacity health and resistance growth.
R_branch has shape (series, parallel) and R_link has length series + 1. Equivalent circuits give each RC branch its own (series, parallel) arrays: the polarization voltages U_1, U_2, … and the branch elements R_1, C_1, …. The equation count follows the topology and the RC order, not the pack dimensions. SOC_initial, T_initial and the thermal ECM parameter heat_capacity have shape (series, parallel); initial SOC and temperature also accept a scalar in Julia. The default heat capacity is one J/K, a generic component parameter rather than a value identified by the electrical literature. Set it for a thermal cell model.
The pins use the shared passive connector convention and I is discharge-positive. Thermal models expose two ArrayHeatPorts. Use cell_views for individual cell fields. Numerical assembly must retain array equations; the ordinary scalarizing mtkcompile route does not preserve pack compilation scaling.
BatteryComponents.ArrayHeatPort — MethodThermal boundary for a battery pack, with one independent temperature and inward heat flow per series row.
BatteryComponents.BattXCircuit — MethodBattXCircuit(; name, degradation, N, temperature, capacity, SOCinitial, Tref, eta, sigma)
BattX electrical topology: BattXLaw wired to the shared ECMCell interface. Elements are ordinary bindable circuit inputs, so a parameter set may give a table or a (SOC, T) callable for any of them even though the published fit (BijuFang2022) uses only constants.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
N | – | 5 | |
temperature | – | false | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 | |
T_ref | – | 298.15 | |
eta | – | [1.0, 0.606...48, 0.0164] | |
sigma | – | [1.0, 1.77,...15.98, 0.0] |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)Rs1- This connector represents a real signal as an input to a component (RealInput)Cs1- This connector represents a real signal as an input to a component (RealInput)Re- This connector represents a real signal as an input to a component (RealInput)Ce- This connector represents a real signal as an input to a component (RealInput)Rcore- This connector represents a real signal as an input to a component (RealInput)Ccore- This connector represents a real signal as an input to a component (RealInput)Rsurf- This connector represents a real signal as an input to a component (RealInput)Csurf- This connector represents a real signal as an input to a component (RealInput)alpha- This connector represents a real signal as an input to a component (RealInput)beta- This connector represents a real signal as an input to a component (RealInput)gamma- This connector represents a real signal as an input to a component (RealInput)kappa- This connector represents a real signal as an input to a component (RealInput)q_left- This connector represents a real signal as an input to a component (RealInput)q_right- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
Q_loss | – |
BatteryComponents.BattXLaw — MethodBattXLaw(; name, N, temperature, SOCinitial, Tref, eta, sigma)
BattX coupled-circuit physics: solid-phase diffusion, electrolyte diffusion, lumped core/surface thermal states and the terminal voltage law. Biju and Fang (2022), arXiv:2211.05999, equations (1)-(9). Current here is discharge-positive (I); the paper's I is charge-positive, so every relation below substitutes I_c = -I for the paper's symbol.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
N | – | 5 | |
temperature | – | false | |
SOC_initial | – | 1.0 | |
T_ref | – | 298.15 | |
eta | – | [1.0, 0.606...48, 0.0164] | |
sigma | – | [1.0, 1.77,...15.98, 0.0] |
Connectors
I- This connector represents a real signal as an input to a component (RealInput)SOC- This connector represents a real signal as an input to a component (RealInput)q_left- This connector represents a real signal as an input to a component (RealInput)q_right- This connector represents a real signal as an input to a component (RealInput)Rs1- This connector represents a real signal as an input to a component (RealInput)Cs1- This connector represents a real signal as an input to a component (RealInput)Re- This connector represents a real signal as an input to a component (RealInput)Ce- This connector represents a real signal as an input to a component (RealInput)Rcore- This connector represents a real signal as an input to a component (RealInput)Ccore- This connector represents a real signal as an input to a component (RealInput)Rsurf- This connector represents a real signal as an input to a component (RealInput)Csurf- This connector represents a real signal as an input to a component (RealInput)alpha- This connector represents a real signal as an input to a component (RealInput)beta- This connector represents a real signal as an input to a component (RealInput)gamma- This connector represents a real signal as an input to a component (RealInput)kappa- This connector represents a real signal as an input to a component (RealInput)V- This connector represents a real signal as an output from a component (RealOutput)Q- This connector represents a real signal as an output from a component (RealOutput)
Variables
| Name | Description | Units |
|---|---|---|
V_s | – | |
V_e | – | |
T_core | – | |
T_surf | – | |
eta_weighted | – | |
SOC_solid | – | |
Ro_T | – | |
Rs1_T | – | |
Us_bulk | – | |
Us_surf | – | |
Ue | – |
BatteryComponents.BatteryCell — MethodBatteryCell(; name, model = SPM(), chemistry = default_parameters(model), kwargs...)A BatteryPack with series = parallel = 1, using exactly the same array representation, electrical pins and thermal connectors. Constitutive options are forwarded to the pack builder. Electrochemical models are thermal by default; ECMs are isothermal unless a thermal model and heat capacity are supplied.
Use only(cell_views(cell)) for the cell's symbolic states and parameters, including SOC_initialₒcell and T_cell. The component itself exposes pack quantities such as V, I, SOC and T. Compile its circuit with mtkcompile and build an ODEProblem as for any ModelingToolkit component.
BatteryComponents.BatteryPack — MethodBatteryPack(; name, model = SPM(), chemistry = default_parameters(model),
series = 1, parallel = 1, R_connection = 0.0, wiring = :parallel_groups,
coolant_axis = :none, kwargs...)A shared array pack with scalar electrical pins p and n. ECM and SPM/SPMe/DFN constitutive models use the same network. A cell is the 1×1 case. Current entering p charges the pack; reported I = -p.i is discharge-positive.
Cell fields and parameters retain (series, parallel) pack axes. Access individual cells with cell_views. Thermal variants expose two ArrayHeatPorts with (series, 1) temperatures and heat flows. Parallel neighbors exchange heat within each series row. With thermal_network = PackThermalNetwork(...), the pack exposes heatport_coolant; coolant_axis = :none makes it scalar, while :series or :parallel assigns one (N, 1) coolant port entry per slice of that axis (scalar for N = 1). A directional coolant_axis requires a thermal network; valid values are :none, :series and :parallel, including for isothermal packs. R_connection defaults each cell branch and each of the series + 1 series links; R_branch and R_link can provide separate arrays.
wiring chooses the order in which the grid is connected, the choice Modelica.Electrical.Batteries makes with useAllParallelConnections:
:parallel_groups(the default) wiresparallelcells in parallel and those groups in series, so every cell of a series row shares a row voltage and the groups share the pack current;:series_stringswiresseriescells in series and those strings in parallel, so every cell of a string carries the same string current and the strings share the pack voltage.
Identical cells split the current evenly under either wiring, so with ideal connections the two differ only when the cells do — which is the case a mixed pack is built to study. R_branch stays in series with its cell either way; R_link does not, because the links move, and that separates the two wirings even for identical cells. With :parallel_groups all series + 1 links carry the pack current. With :series_strings the interior links R_link[2:series] sit inside each string and carry that string's current, and only R_link[1] and R_link[series + 1] carry the pack current. The thermal coupling describes physical adjacency in the grid and is unaffected by wiring.
The pack reports V, I, P, SOC, SOC_abs, SOH, T, Q, Q_theoretical and C_rate. Q_interconnect reports connection-resistor loss. The remaining options are those of the constitutive model. The symbolic model is a fixed set of array equations whose size does not depend on series × parallel; mtkcompile currently scalarizes them, so compiled and numerical work grow with the cell count.
BatteryComponents.BijuFang2022 — MethodBijuFang2022()BattX parameters for the Samsung INR18650-25R cell of [1] (NCA cathode, graphite anode; 2.5 A⋅h nominal capacity, 3.6 V nominal, 4.2 V/2.5 V cut-offs, 20 A maximum continuous discharge — Section 5's cell specification), identified in [1]'s Section 5.1 by the grouped procedure of its Section 4.
Every entry below is the final estimate column of the identification tables, not the initial guess or the bound; the citations name the exact table.
"solid open-circuit voltage coefficients"(α₀…α₁₆,Θ̂_Us): Section 5.1, first bullet, the 17-number vector printed there ({-9.048, ..., 1.816}). Fitted from a 1/30 C full charge/discharge (Fig. 4)."series resistance coefficients"(γ₁, γ₂, γ₃),"solid diffusion capacitance"(C_s,1),"solid diffusion resistance"(R_s,1), and the four thermal entries (C_surf,R_surf,C_core,R_core): Table 1's Final estimate row. Table 1 also gives the identification's initial guesses and bounds (Cs,1 ∈ [3600, 5500],Rs,1 ∈ [0.054, 0.167],Csurf ∈ [3, 12],Rsurf ∈ [3, 20],Ccore ∈ [5, 50],Rcore ∈ [0.5, 7]), not carried here."electrolyte diffusion capacitance"(C_e),"electrolyte diffusion resistance"(R_e),"electrolyte voltage coefficients"(β₁, β₂) and"Arrhenius coefficients"(κ₁forR_o,T,κ₂forR_s1,T): Table 2's Final estimate row."solid diffusion capacitance ratios"(η) and"solid diffusion resistance ratios"(σ): Section 5.1, third bullet, the 5-node discretization (η = {1, 0.6066, 0.3115, 0.1148, 0.0164},σ = {1, 1.77, 4.00, 15.98}), matchingBattX's defaultN = 5."nominal capacity": 2.55 A⋅h, the Coulomb-counted total from Section 5.1's first bullet. It is a different, independently measured number from the capacityΣ ηᵢ C_s,1 ≈ 2.574 A⋅himplied byηandC_s,1above (about 1% apart); this set keeps both as [1] reports them rather than forcing one to match the other — seeBattX's docstring.
Table 1's final estimate is γ₃ = -14.36. Substituted into equation (8), Ro(SoC) = γ₁ + γ₂ exp(-γ₃ SoC), the exponent's sign flips from decaying to growing: Ro(0.2) ≈ 1.1 Ω, Ro(0.8) ≈ 5950 Ω, Ro(1.0) ≈ 1.05×10⁵ Ω, against Fig. 5b's plotted range of about 0.025-0.045 Ω over the same SoC window and against Table 1's own initial guess of γ₃ = 1 (positive, and decaying). This set preserves the printed -14.36; the inconsistency alone does not establish that the sign is the error rather than, say, a mislabeled column. Overriding cell.gamma_3 => 14.36 reproduces a monotonically decreasing Ro(SoC) of the shape Fig. 5b plots, but that is an assumption, not an author-confirmed correction.
No parameter set here reports "heat capacity", "self-discharge current", "coulombic efficiency" or "entropic coefficient"; BattX has no use for the first (its own core/surface network replaces the shared lumped mass under temperature = true — see BattX) and [1] does not identify the rest.
Bounds are the cell's voltage cut-offs (Section 5, 4.2 V/2.5 V) and continuous-discharge current (20 A); [1] gives no state-of-charge or temperature cut-off.
Not verified against held-out measured data. [1]'s own validation (Figs. 6, 8-13) plays back digitized bench measurements that are not published alongside the paper; see the BattX report accompanying this parameter set for what was checked instead (the governing equations against an independent closed-form solution, and internal consistency such as charge conservation).
[1] Nikhil Biju and Huazhen Fang. "BattX: An Equivalent Circuit Model for Lithium-Ion Batteries Over Broad Current Ranges." arXiv:2211.05999 (2022), Tables 1-2 and Section 5.1. https://arxiv.org/abs/2211.05999
BatteryComponents.BulkSurfaceCircuit — MethodBulkSurfaceCircuit(; name, degradation, capacity, SOC_initial, U0)
SAFT bulk/surface topology with supplied element signals and initial rest voltage U0.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 | |
U0 | – | 3.7 |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)r_t- This connector represents a real signal as an input to a component (RealInput)r_e- This connector represents a real signal as an input to a component (RealInput)r_c- This connector represents a real signal as an input to a component (RealInput)c_b- This connector represents a real signal as an input to a component (RealInput)c_c- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
Q_loss | – |
BatteryComponents.BulkSurfaceECM — MethodBulkSurfaceECM(; name, degradation, capacity, SOCinitial, U0, Rt, Re, Rc, Cb, Cc)
SAFT RC cell with constant elements; He et al. (2011), equation (2).
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 | |
U0 | – | 3.7 | |
R_t | – | 0.01 | |
R_e | – | 0.01 | |
R_c | – | 0.01 | |
C_b | – | 10000.0 | |
C_c | – | 1000.0 |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)r_t- This connector represents a real signal as an input to a component (RealInput)r_e- This connector represents a real signal as an input to a component (RealInput)r_c- This connector represents a real signal as an input to a component (RealInput)c_b- This connector represents a real signal as an input to a component (RealInput)c_c- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
Q_loss | – |
BatteryComponents.CPEMode — MethodCPEMode(; name)
RC branch k of n of a CPE impedance 1/(Q s^alpha): midpoint rule in ln(x) for s^-alpha = sin(pi alpha)/pi * integral of x^-alpha/(s + x), nodes over 2 pi [flow, fhigh].
Connectors
Q- This connector represents a real signal as an input to a component (RealInput)alpha- This connector represents a real signal as an input to a component (RealInput)f_low- This connector represents a real signal as an input to a component (RealInput)f_high- This connector represents a real signal as an input to a component (RealInput)k- This connector represents a real signal as an input to a component (RealInput)n- This connector represents a real signal as an input to a component (RealInput)R- This connector represents a real signal as an output from a component (RealOutput)C- This connector represents a real signal as an output from a component (RealOutput)
BatteryComponents.CPETail — MethodCPETail(; name)
Tails of the CPE ladder: relaxations below 2 pi flow as the series capacitor C, relaxations above 2 pi fhigh as the series resistor R.
Connectors
Q- This connector represents a real signal as an input to a component (RealInput)alpha- This connector represents a real signal as an input to a component (RealInput)f_low- This connector represents a real signal as an input to a component (RealInput)f_high- This connector represents a real signal as an input to a component (RealInput)R- This connector represents a real signal as an output from a component (RealOutput)C- This connector represents a real signal as an output from a component (RealOutput)
BatteryComponents.ChenRinconMora2006 — MethodChenRinconMora2006()Equivalent circuit parameters for the 850 mA⋅h TCL PL-383562 polymer lithium-ion cell of [1], at room temperature. Every element is a function of the state of charge, fitted in [1] (its equations 2-7) to pulse-discharge data at 80, 160, 320 and 640 mA:
| element | entry |
|---|---|
OCV | "open-circuit voltage" |
R_Series | "series resistance" |
R_TransientS, R_TransientL | "polarization resistance" |
C_TransientS, C_TransientL | "polarization capacitance" |
The two RC pairs are the short and the long time constant of the step response, in that order, which makes the set the natural one for DP (or Thevenin(2)); Thevenin with the default n = 1 keeps the short pair alone and Rint neither. It parameterizes no PNGV capacitor and none of the RCModel elements — see He2011LiMn2O4 for those.
The stop conditions are the cell's test limits from [1]: 4.1 V constant-voltage charge with a 10 mA end-of-charge current, charge current below 800 mA, 3.0 V end of discharge. The SOC_min bound of 0.02 is not from [1]: the fitted capacitances of its equations 5 and 7 cross zero at about 0.5% and 1.1% state of charge, so the model has to be kept above that, and [1] reports the fits degrading below 10% state of charge in any case.
temperature = true needs a "heat capacity", which [1] does not report.
[1] Min Chen and Gabriel A. Rincón-Mora. "Accurate Electrical Battery Model Capable of Predicting Runtime and I-V Performance." IEEE Transactions on Energy Conversion 21, no. 2 (2006): 504-511. https://doi.org/10.1109/TEC.2006.874229
BatteryComponents.ChenRinconMoraECM — MethodChenRinconMoraECM(; name, degradation, nrc, capacity, SOCinitial)
Chen and Rincon-Mora (2006), equations (2)-(7), 850 mAh polymer Li-ion cell at room temperature. Use within SOC 0.02-1; no aging or self-discharge is fitted. DOI: 10.1109/TEC.2006.874229.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
n_rc | – | 2 | |
capacity | – | 0.85 | |
SOC_initial | – | 1.0 |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)r0- This connector represents a real signal as an input to a component (RealInput)r- This connector represents a real signal as an input to a component (RealInput)c- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
U | – | |
losses | – | |
Q_loss | – | |
OCV | – |
BatteryComponents.Cycler — MethodCycler(; name, protocol, capacity, bounds = (;))
Cycler(; name, state = CyclerState())A battery cycler as a ModelingToolkit component: an electrical source with the pins p and n that imposes a current, a voltage or a power on the connected battery and switches between the steps of a cycling protocol on events. CyclingCircuit wires one up with a BatteryPack and a ground; build the circuit by hand when the battery is part of a larger model.
protocol is an experiment or a vector of experiments (charge, discharge, voltage, power, rest); C-rates in it are converted with capacity (A⋅h, see capacity_pack). bounds are the default stop conditions, e.g. (V_min = 2.7, V_max = 4.2, SOC_min = 0.0, SOC_max = 1.0). state is the CyclerState the cycler logs into; pass one in and read it back with experiment_results to get the exit reasons.
@named cell = BatteryCell(; model = SPM(), chemistry = NMC(), temperature = false)
@named cycler = Cycler(; protocol = [charge(1C), voltage(hold), rest(time = 600)],
capacity = 5.0, bounds = (V_max = 4.2, I_min = 0.25))
@named ground = Ground()
eqs = [connect(cell.p, cycler.p); connect(cycler.n, cell.n); connect(cell.n, ground.g);
cycler.SOC_in.u ~ cell.SOC; cycler.T_in.u ~ cell.T]
sys = mtkcompile(System(eqs, t; systems = [cell, cycler, ground], name = :circuit))
prob = ODEProblem(sys, [only(cell_views(cell)).SOC_initialₒcell => 0.2], (0.0, 1e5))
sol = solve(prob, FBDF())All battery models use the same passive electrical connectors. Positive cycler current enters its p pin and leaves the battery's positive pin during discharge.
Variables: I (positive when the connected battery discharges), v (voltage across the pins) and P = I v. The inputs SOC_in and T_in (RealInputs) take the state of charge and the temperature the stop conditions refer to.
Parameters: the default stop conditions I_min, I_max, V_min, V_max, P_min, P_max, T_min, T_max, SOC_min, SOC_max (NaN disables one; current and power bounds apply to the magnitude), the current step step, its mode (1 current, 2 voltage, 3 power), setpoint X_app and end time t_end, and the stop conditions in force during the step (I_min_step, ...).
Events: a step ends when its end time is reached or when one of its stop conditions is hit (continuous events on t - t_end, |I| - I_max_step, V_min_step - V, ...). The affect logs the end of the step in state and loads the parameters of the next step of state.steps, skipping steps whose stop conditions are already violated, and terminates the integration after the last step. The DAE is re-initialized with BrownFullBasicInit after every switch.
Other sources and loads can share the battery's pins with the cycler. Since the operating mode is a parameter, the battery current is an algebraic unknown of the compiled system, and an input that jumps makes that unknown jump. Such a jump has to happen in an event that re-initializes the DAE: written into the equations as a function of time (ifelse(t < 10, 0.0, 5.0) or a registered function), it can leave the solver unable to step across it, and solve returns ReturnCode.Unstable. For an extra 5 A load switched on at 10 s, with DiffEqBase imported:
@named load = Current()
@discretes I_load(t) = 0.0
switch_on = ModelingToolkit.ImperativeAffect((m, o, ctx, integ) -> (; I_load = 5.0);
modified = (; I_load))
events = [ModelingToolkit.SymbolicDiscreteCallback([10.0], switch_on;
reinitializealg = DiffEqBase.BrownFullBasicInit())]
eqs = [eqs; connect(load.p, cell.p); connect(load.n, cell.n); load.I.u ~ I_load]
sys = mtkcompile(System(eqs, t, [], [I_load]; systems = [cell, cycler, ground, load],
discrete_events = events, name = :circuit))BatteryComponents.CyclingCircuit — MethodCyclingCircuit(; name, model = SPM(), chemistry = default_parameters(model),
series = 1, parallel = 1, protocol, bounds = (;), R_connection = 0.0,
T_ambient = 298.15, heat_transfer_coefficient = 1.0, cooling = nothing,
state = CyclerState(), kwargs...)A BatteryPack, the shared Cycler, ground and optional native PackAmbient boundaries. Thermal coupling uses two array connectors, independently of pack dimensions. T_ambient accepts a scalar or a (series, 1) array. The same electrical convention and protocol apply to every model family.
cooling = ForcedAirCooling(...) replaces the fixed ambient with a PackForcedAir boundary named cooler: a fan switched by a thermostat on the pack's hottest cell temperature, blowing air at T_ambient over a case. With the per-row heat ports each row face reaches the case node through heat_transfer_coefficient; with a thermal_network the case nodes are the network's coolant. cooling.flow_axis selects one node (:none) or an inlet-to-outlet chain along :series or :parallel; the inlet is at index 1. See PackForcedAir for the port geometry and energy balances.
Compile with mtkcompile and solve with a stiff ODE/DAE algorithm such as FBDF. For example:
@named circuit = CyclingCircuit(; model = SPM(), series = 2, parallel = 3,
temperature = false, SEI_degradation = false,
protocol = [discharge_current(0.3; time = 10), rest(time = 5)])
cells = cell_views(circuit)
sys = mtkcompile(circuit)
prob = ODEProblem(sys, [c.SOC_initialₒcell => 0.6 for c in cells], (0.0, 30.0))
sol = solve(prob, FBDF())The circuit exposes the pack quantities directly. Per-cell states and parameters are available through cell_views; it contains no cell_s_p subsystems. The integration terminates after the final protocol step, and state records the step boundaries for experiment_results.
BatteryComponents.DualPolarizationECM — MethodDualPolarizationECM(; name, degradation, nrc, capacity, SOCinitial, R0, R, C)
Dual polarization is the two-branch Thevenin topology.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
n_rc | – | 2 | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 | |
R0 | – | 0.01 | |
R | – | fill(0.01, n_rc) | |
C | – | fill(1000.0, n_rc) |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)r0- This connector represents a real signal as an input to a component (RealInput)r- This connector represents a real signal as an input to a component (RealInput)c- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
U | – | |
losses | – | |
Q_loss | – |
BatteryComponents.ECMBulkSurface — MethodECMBulkSurface(; name, U_initial)
SAFT bulk/surface capacitor network: He et al. (2011), equation (2).
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
U_initial | – | 3.7 |
Connectors
I- This connector represents a real signal as an input to a component (RealInput)R_t- This connector represents a real signal as an input to a component (RealInput)R_e- This connector represents a real signal as an input to a component (RealInput)R_c- This connector represents a real signal as an input to a component (RealInput)C_b- This connector represents a real signal as an input to a component (RealInput)C_c- This connector represents a real signal as an input to a component (RealInput)OCV- This connector represents a real signal as an output from a component (RealOutput)V- This connector represents a real signal as an output from a component (RealOutput)Q- This connector represents a real signal as an output from a component (RealOutput)
Variables
| Name | Description | Units |
|---|---|---|
U_b | – | |
U_c | – | |
i_b | – | |
i_c | – |
BatteryComponents.ECMCharge — MethodECMCharge(; name, capacity, SOC_initial)
Coulomb counting in seconds and ampere-hours, with discharge-positive current.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
capacity | – | 1.0 | |
SOC_initial | – | 1.0 |
Connectors
I- This connector represents a real signal as an input to a component (RealInput)health- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOC | – |
BatteryComponents.ECMHealth — MethodECMHealth(; name, degradation)
Health interface for independently calibrated aging laws. SOH is available/nominal capacity; resistance_factor scales resistances only.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – |
BatteryComponents.ECMNDCNetwork — MethodECMNDCNetwork(; name, V_initial)
NDC bulk/surface charge-transport network, with no terminal formula of its own: Tian, Fang, Chen and Wang (2020), the (Vb, Vs) block of equation (1a). Vb and Vs are dimensionless charge fractions (Section II normalizes both to lie in [0, 1], as SOC does) rather than voltages; the nonlinear terminal voltage is a function of V_s built outside this component.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
V_initial | – | 1.0 |
Connectors
I- This connector represents a real signal as an input to a component ((RealInput))R_e- This connector represents a real signal as an input to a component ((RealInput))R_c- This connector represents a real signal as an input to a component ((RealInput))C_b- This connector represents a real signal as an input to a component ((RealInput))C_c- This connector represents a real signal as an input to a component ((RealInput))Q- This connector represents a real signal as an output from a component ((RealOutput))
Variables
| Name | Description | Units |
|---|---|---|
V_b | – | |
V_s | – | |
i_b | – | |
i_c | – |
BatteryComponents.ECMOCVDrift — MethodECMOCVDrift(; name)
Series storage capacitor; positive discharge current increases the voltage loss.
Connectors
I- This connector represents a real signal as an input to a component (RealInput)C- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
U | – |
BatteryComponents.ECMOhmic — MethodECMOhmic(; name)
Ohmic voltage loss and resistor dissipation, with discharge-positive current.
Connectors
I- This connector represents a real signal as an input to a component (RealInput)OCV- This connector represents a real signal as an input to a component (RealInput)R- This connector represents a real signal as an input to a component (RealInput)V- This connector represents a real signal as an output from a component (RealOutput)Q- This connector represents a real signal as an output from a component (RealOutput)
BatteryComponents.ECMPolarization — MethodECMPolarization(; name, U_initial)
Polarization branch: He et al. (2011), equation (3). R and C may vary with SOC.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
U_initial | – | 0.0 |
Connectors
I- This connector represents a real signal as an input to a component (RealInput)R- This connector represents a real signal as an input to a component (RealInput)C- This connector represents a real signal as an input to a component (RealInput)Q- This connector represents a real signal as an output from a component (RealOutput)
Variables
| Name | Description | Units |
|---|---|---|
U | – |
BatteryComponents.ECMThermalMass — MethodECMThermalMass(; name, Cth, Tinitial)
Lumped thermal balance; Q is an explicitly supplied heat law, not inferred from fitted RC storage.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
C_th | – | 1.0 | |
T_initial | – | 298.15 |
Connectors
Q- This connector represents a real signal as an input to a component (RealInput)left- This connector represents a thermal port with temperature and heat flow as the potential and flow variables, respectively. (HeatPort)right- This connector represents a thermal port with temperature and heat flow as the potential and flow variables, respectively. (HeatPort)
Variables
| Name | Description | Units |
|---|---|---|
T | – |
BatteryComponents.EDLCParameters — MethodEDLCParameters(; capacitance, rated_voltage, series_resistance,
minimum_voltage = rated_voltage / 2, initial_state_of_charge = 1.0,
initial_temperature = 298.15u"K", heat_capacity = nothing)The parameter set of an EDLC cell, built from the three numbers a double-layer capacitor is actually sold by: a capacitance [F], a rated_voltage [V] and an equivalent series_resistance [Ω]. This is the constructor to reach for when modelling a device from its datasheet; MaxwellPC2500 is a worked example of its use.
capacitance and rated_voltage must be constants, since together they fix the charge C V_rated that the state of charge counts against. series_resistance is an ordinary circuit element and may also be a (SOC, T) callable in SI units, which is how a temperature-dependent equivalent series resistance is supplied.
The stop conditions are the voltage window minimum_voltage to rated_voltage; no current, power, state-of-charge or temperature bound is set, since a capacitor datasheet states none that maps onto one. minimum_voltage defaults to half the rated voltage, the conventional floor that leaves three quarters of the stored energy delivered and, being V_oc / 2, is also where a series-resistance-limited discharge reaches its maximum power. Pass heat_capacity [J/K] to build the cell with temperature = true.
BatteryComponents.ESCCircuit — MethodESCCircuit(; name, nrc, degradation, capacity, SOCinitial, hinitial, sinitial, threshold, i_initial)
Continuous ESC circuit with event-driven current-sign memory and arbitrary RC order.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
n_rc | – | 1 | |
degradation | – | ECMDegradat...gradation() | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 | |
h_initial | – | 0.0 | |
s_initial | – | 0.0 | |
threshold | – | 1e-8 | |
i_initial | – | zeros(n_rc) |
Connectors
p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)r0- This connector represents a real signal as an input to a component (RealInput)eta_charge- This connector represents a real signal as an input to a component (RealInput)M- This connector represents a real signal as an input to a component (RealInput)M0- This connector represents a real signal as an input to a component (RealInput)gamma- This connector represents a real signal as an input to a component (RealInput)r- This connector represents a real signal as an input to a component (RealInput)c- This connector represents a real signal as an input to a component (RealInput)capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
I | – | |
V | – | |
SOC | – | |
SOH | – | |
resistance_factor | – | |
eta | – | |
h | – | |
s | – | |
U | – | |
losses | – | |
Q_loss | – |
BatteryComponents.ESCCurrentSign — MethodESCCurrentSign(; name, threshold = 1e-8, s_initial = 0.0)Discrete last-current sign for the native ESCCircuit. Input I is in amperes. Output s is the direction of I while abs(I) >= threshold and holds inside the band: continuous events update it at outward threshold crossings, and a discrete event after a step in which I jumped across the band inside another event. Initialization uses the solved initial current, or s_initial inside the band.
BatteryComponents.ESCHysteresis — MethodESCHysteresis(; name, h_initial)
Hysteresis voltage loss: Plett, ECE5710 Notes 02, pages 2-11 through 2-13.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
h_initial | – | 0.0 |
Connectors
I- This connector represents a real signal as an input to a component (RealInput)eta- This connector represents a real signal as an input to a component (RealInput)capacity- This connector represents a real signal as an input to a component (RealInput)M- This connector represents a real signal as an input to a component (RealInput)gamma- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
h | – |
BatteryComponents.ESCPolarization — MethodESCPolarization(; name, i_initial)
RC branch current: Plett, ECE5710 Notes 02, page 2-14.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
i_initial | – | 0.0 |
Connectors
I- This connector represents a real signal as an input to a component (RealInput)R- This connector represents a real signal as an input to a component (RealInput)C- This connector represents a real signal as an input to a component (RealInput)U- This connector represents a real signal as an output from a component (RealOutput)Q- This connector represents a real signal as an output from a component (RealOutput)
Variables
| Name | Description | Units |
|---|---|---|
i_R | – |
BatteryComponents.ESCTerminal — MethodESCTerminal(; name)
ESC terminal equation: Plett, ECE5710 Notes 02, page 2-15; h is a voltage loss.
Connectors
I- This connector represents a real signal as an input to a component (RealInput)OCV- This connector represents a real signal as an input to a component (RealInput)R0- This connector represents a real signal as an input to a component (RealInput)M0- This connector represents a real signal as an input to a component (RealInput)s- This connector represents a real signal as an input to a component (RealInput)h- This connector represents a real signal as an input to a component (RealInput)polarization- This connector represents a real signal as an input to a component (RealInput)V- This connector represents a real signal as an output from a component (RealOutput)Q- This connector represents a real signal as an output from a component (RealOutput)
BatteryComponents.EquivalentCircuitCell — MethodEquivalentCircuitCell(; name, topology, degradation, nrc, capacity, SOCinitial, R0, R, C, Rdp, Cdp, U0, Cocv, Rt, Re, Rc, Cb, Cc)
Native Dyad ECM selector. All circuit alternatives are native components. Parameters are SI except capacity in Ah. PrescribedHealth requires two health signals; it is not a fitted aging law.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
topology | – | ECMTopology.Thevenin() | |
degradation | – | ECMDegradat...gradation() | |
n_rc | – | 1 | |
capacity | – | ifelse(__dy... 0.85, 1.0) | |
SOC_initial | – | 1.0 | |
R0 | – | 0.01 | |
R | – | fill(0.01, n_rc) | |
C | – | fill(1000.0, n_rc) | |
R_dp | – | [0.01, 0.01] | |
C_dp | – | [1000.0, 1000.0] | |
U0 | – | 3.7 | |
C_ocv | – | 10000.0 | |
R_t | – | 0.01 | |
R_e | – | 0.01 | |
R_c | – | 0.01 | |
C_b | – | 10000.0 | |
C_c | – | 1000.0 |
Connectors
p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
I | – | |
V | – | |
SOC | – | |
SOH | – | |
Q_loss | – |
BatteryComponents.EquivalentCircuitParameters — MethodEquivalentCircuitParameters(; overall, circuit, bounds = Dict{String, Any}())An equivalent circuit parameter set, the chemistry of a cell built with one of the EquivalentCircuitModels. See ChenRinconMora2006 and He2011LiMn2O4 for the two faradaic sets shipped here and MaxwellPC2500 for the capacitor, and copy one to write your own.
overall holds the cell as a whole, all of it optional: "nominal capacity" [A⋅h, the capacity the state of charge is counted against, derived rather than read for an EDLC], "initial state of charge", "initial temperature" [K, the temperature of an isothermal cell], "heat capacity" [J/K, needed only for temperature = true] and "entropic coefficient" [V/K, dOCV/dT, zero by default].
Two further entries act on the coulomb counter and are off unless the set asks for them. "self-discharge current" [A] is the current the cell loses to itself at full charge, the way Modelica.Electrical.Batteries parameterizes its parallel conductor: the conductance is that current over the open-circuit voltage at full charge, so the loss falls with the state of charge and its power is dissipated in the cell. "coulombic efficiency" [1, one by default] is the fraction of a charging current that reaches the stored charge; the rest becomes heat at the terminal voltage, and a discharging current is unaffected.
"nominal capacity" and "coulombic efficiency" may also be callables T -> value of the cell temperature, in A⋅h and as a fraction, or a LookupTable over temperature alone — the C(T) and η(T) of ADVISOR's Rint model. A temperature-dependent capacity changes the bookkeeping the way ADVISOR's does: the cell then integrates the charge drawn from full, q_drawn [A⋅h], and reports SOC = 1 - q_drawn / (C(T) SOH), starting from "initial state of charge" at the initial temperature. Charge is conserved, and a cell at rest changes its state of charge when a temperature change moves its capacity; integrating the state of charge against a moving capacity instead would make the charge a cycle returns depend on the temperatures it was drawn at. cell_capacity, theoretical_capacity and C_rate follow C(T). With a constant capacity the state of charge itself is the integrated state, as before. Either callable is evaluated at "initial temperature" unless the cell is built with temperature = true.
circuit holds the circuit elements, which keys depend on the model — see Rint, Thevenin, DP, PNGV, RCModel and EDLC. Each entry is a constant, with or without a Unitful unit, which becomes a parameter of the component that a problem can override; a LookupTable interpolating a measured grid over (SOC, T), which becomes a nonnumeric parameter holding the table that a problem can replace just as well; or any other callable (SOC, T) -> value in SI units, which is inlined as an expression in the state of charge and the cell temperature and cannot be overridden. Where the set identifies elements per model, as He2011LiMn2O4 does, a subsection named after the model ("DP", "PNGV", …) overrides the common entries.
The models with a series resistance (Rint, Thevenin, DP, PNGV, EDLC) take it either as one "series resistance" or as a "discharge resistance" and a "charge resistance" pair, selected by the sign of the current the way ADVISOR's Rint tables are: R_0 is the discharge value while the reported current I is positive (discharging) and the charge value while it is negative. Both keys are needed, and a set that gives the pair as well as "series resistance" is rejected rather than read two ways. Every shipped set but SaftLiIon6Ah uses the single entry.
bounds holds the default stop conditions of a Cycler driving the cell, keyed "voltage maximum", "current minimum", … over voltage, current, power, state of charge and temperature. A bound left out is disabled.
BatteryComponents.He2011LiMn2O4 — MethodHe2011LiMn2O4()Equivalent circuit parameters for the 100 A⋅h, 57.6 V nominal LiMn₂O₄ battery module of [1], identified with a genetic algorithm from a hybrid pulse power characterization (HPPC) test. It is the one published set that covers all five topologies of the same cell, which is what makes them comparable, and the only one here that parameterizes PNGV and RCModel.
The identification is local. [1] reports one parameter set per model at 50% and at 60% state of charge (its tables 1-5) and nothing outside that window, so:
- the elements here are the 50% row, held constant. How far the 60% row moves is a fair measure of how local the fit is: under 2% for the ohmic resistances and for every
DPelement, but 4% and 12% for the resistance and the capacitance of theTheveninRC pair, and 21% and 12% for the bulk and the surface capacitance of theRCModel; - the open-circuit voltage is the straight line through the two reported points, which means the module's real curvature is missing and extrapolating outside 0.5-0.6 is meaningless. The default
SOC_min/SOC_maxbounds are 0.5 and 0.6 for that reason, and the default initial state of charge is 0.55; - every other bound is
NaN, i.e. disabled: an HPPC test reports no cut-off voltages, currents or temperatures, so there are none to take from [1].
Each model gets its own subsection, since [1] identifies the elements per model — across the Rint, Thevenin, PNGV and DP tables the U_oc values agree to 0.3% and the R_0 values to 3%, but they are not the same numbers. Thevenin(n) for n > 1 has no entry: use DP for the second-order fit.
Table 5 prints Cpc = 54277 F, Rpc = 0.00824 Ω and τpc = 44.7 s. Their product is 447.24248 s, not 44.7 s. This set preserves the printed R and C; the inconsistency alone does not establish which entry is wrong. To investigate the alternative interpretation, override cell.C_2 => 5427.7 explicitly. That value is an assumption, not an author-confirmed correction or a new calibration.
temperature = true needs a "heat capacity", which [1] does not report.
[1] Hongwen He, Rui Xiong and Jinxin Fan. "Evaluation of Lithium-Ion Battery Equivalent Circuit Models for State of Charge Estimation by an Experimental Approach." Energies 4, no. 4 (2011): 582-598. https://doi.org/10.3390/en4040582
BatteryComponents.LCO — MethodLCO()Default parameters for a lithium cobalt oxide (LCO) cell.
This is the reference cell of the LIONSIMBA toolbox [1] — there called the "Northrop cell". The electrode, separator, electrolyte and thermal values below are those of Table IV of [1] and Table III of [2] (the active-material fractions as one minus porosity minus filler fraction), and the physics functions those of Table II of [1] and Tables II and VII of [2]; all of them also match Parameters_init.m and the physics routines of LIONSIMBA. [1] states that the parameters describing the chemistry are taken from [2]. Not printed in either paper:
- the stoichiometry limits, which are those of LIONSIMBA's
Parameters_init.m; the papers give only the initial concentrations, 25751 and 26128 mol/m³ - the zero initial film resistance and the SEI exchange current density, which belong to this package's SEI submodel (see
SEI_degradation_default_params) - the nominal capacity, which is LIONSIMBA's 1C current density of 29.23 A/m² re-expressed as a capacity over the 1 m² cross-section
- the heat transfer coefficient, the voltage bounds and the two current collectors, which are this package's own; LIONSIMBA's collectors differ slightly (copper 8940 kg/m³ and 5.96e7 S/m, aluminium 3.55e7 S/m)
The individual correlations and values, and where they come from:
electrode and separator geometry, transport and kinetics: [2] takes them from Subramanian et al. (2009), https://doi.org/10.1149/1.3065083. Table I of [3] has the same thicknesses, conductivities, porosities, Bruggeman exponent, particle radius, solid diffusivities and negative-electrode maximum concentration, and rate constants of 4.854e-6 and 2.252e-6 (A/m²)(m³/mol)^1.5, the values used here. It differs in the positive-electrode maximum concentration (51555 rather than 51554 mol/m³), the negative-electrode active-material fraction (0.49 rather than 0.4824) and the transference number (0.363 rather than 0.364).
thermal conductivities: Kumaresan, Sikha & White (2008), https://doi.org/10.1149/1.2817888, according to [2]; densities, specific heats and activation energies are marked as assumed values in [2]
open-circuit potentials, both electrodes: [3], Eqs. A-1 and A-2
entropic coefficients ∂U/∂T, both electrodes: [2] Table VII attributes both fits to Guo, Sikha & White (2011), https://doi.org/10.1149/1.3521314. [2] prints the θ⁷ term of the negative-electrode numerator with a minus sign; [1] Table II and the function here have a plus, the only one of the two that gives values of the size of a graphite entropic coefficient (at most 2.5e-4 V/K rather than tens of V/K).
electrolyte diffusivity and ionic conductivity: [4], as printed in [2] Table VII and [1] Table II
[1] Torchio, M., Magni, L., Gopaluni, R. B., Braatz, R. D., & Raimondo, D. M. (2016). LIONSIMBA: A Matlab framework based on a finite volume model suitable for Li-ion battery design, simulation, and control. Journal of The Electrochemical Society, 163(7), A1192–A1205. https://doi.org/10.1149/2.0291607jes
[2] Northrop, P. W. C., Ramadesigan, V., De, S., & Subramanian, V. R. (2011). Coordinate transformation, orthogonal collocation, model reformulation and simulation of electrochemical-thermal behavior of lithium-ion battery stacks. Journal of The Electrochemical Society, 158(12), A1461. https://doi.org/10.1149/2.058112jes
[3] Ramadass, P., Haran, B., Gomadam, P. M., White, R., & Popov, B. N. (2004). Development of first principles capacity fade model for Li-ion cells. Journal of The Electrochemical Society, 151(2), A196. https://doi.org/10.1149/1.1634273
[4] Valøen, L. O., & Reimers, J. N. (2005). Transport properties of LiPF6-based Li-ion battery electrolytes. Journal of The Electrochemical Society, 152(5), A882. https://doi.org/10.1149/1.1872737
BatteryComponents.LFP — MethodLFP()Default parameters for a lithium iron phosphate (LFP) cell: an A123 LFP/graphite cylindrical cell. Every electrode, separator and electrolyte value below matches the Prada2013 parameter set of PyBaMM as it stood up to and including PyBaMM v23.5 (pybamm/input/parameters/lithium_ion/Prada2013.py at tag v23.5); that set was replaced upstream on 2023-07-05 (pybamm-team/PyBaMM#3096) and today's PyBaMM Prada2013 differs in most of its values, so [1]-[5] rather than "PyBaMM Prada2013" are the citations to follow. The reaction rate constants are that file's exchange-current prefactors, 6.48e-7 and 6e-7 (A/m²)(m³/mol)^1.5, which are in the same form as this package's reaction rate constant. The cell-level entries are this package's own: the electrode height and nominal capacity are both scaled by a factor of 8.656359827565312, and the voltage bounds are 2.5/4.2 V where the upstream set had 2.0/4.4 V.
Like most parameter sets of this kind it is assembled from several sources, one or two per physical quantity:
cell format and capacity: [1]
negative electrode (graphite) and separator: [2]
positive electrode (LFP): [3]
negative electrode open-circuit potential: [2]
positive electrode open-circuit potential: [4]
electrolyte diffusivity and ionic conductivity: [5]
[1] Lain, M. J., Brandon, J., & Kendrick, E. (2019). Design strategies for high power vs. high energy lithium ion cells. Batteries, 5(4), 64. https://doi.org/10.3390/batteries5040064
[2] Chen, C.-H., Brosa Planella, F., O'Regan, K., Gastol, D., Widanage, W. D., & Kendrick, E. (2020). Development of experimental techniques for parameterization of multi-scale lithium-ion battery models. Journal of The Electrochemical Society, 167(8), 080534. https://doi.org/10.1149/1945-7111/ab9050
[3] Prada, E., Di Domenico, D., Creff, Y., Bernard, J., Sauvant-Moynot, V., & Huet, F. (2013). A simplified electrochemical and thermal aging model of LiFePO4-graphite Li-ion batteries: power and capacity fade simulations. Journal of The Electrochemical Society, 160(4), A616–A628. https://doi.org/10.1149/2.053304jes
[4] Afshar, S., Morris, K., & Khajepour, A. (2017). Efficient electrochemical model for lithium-ion cells. arXiv preprint arXiv:1709.03970. https://arxiv.org/abs/1709.03970
[5] Nyman, A., Behm, M., & Lindbergh, G. (2008). Electrochemical characterisation and modelling of the mass transport phenomena in LiPF6-EC-EMC electrolyte. Electrochimica Acta, 53(22), 6356–6365. https://doi.org/10.1016/j.electacta.2008.04.023
BatteryComponents.LFP2 — MethodLFP2()Alternative parameters for a lithium iron phosphate (LFP) cell: an LFP/graphite 2 Ah cylindrical 18650 cell, parameterised by About:Energy Limited (aboutenergy.io) in December 2022 from cell cycling data and post-teardown electrode data, and published as the lfp_18650_cell_BPX.json example of the Faraday Institution's BPX standard [1]. The geometry, transport, stoichiometry and activation-energy values of the electrodes and separator, the electrolyte, and both open-circuit potentials match that file. The reaction rate constants are the file's normalised rate constants k [mol/(m²⋅s)], 6.872e-6 and 9.736e-7, converted to this package's exchange-current prefactor as in NMC, F k / (c_max √c_e0) with c_e0 = 1000 mol/m³, which gives 6.678e-7 and 1.401e-7 (A/m²)(m³/mol)^1.5. The differences from [1]:
- the electrode and separator thermal properties are not from [1], which gives only lumped cell values; they are those of
LFP - capacity and area are normalised to a 1 m² cross-section, and the voltage bounds are 2.0/4.4 V where [1] gives 2.0/3.65 V
Its own sources, as stated in the BPX header:
- electrolyte properties: [2]
- negative electrode entropic coefficient: [3]
- positive electrode entropic coefficient: [4] (tabulated in [1]; fitted to a cubic here)
- other thermal properties: estimated
The two open-circuit potentials are the fitted expressions given directly in [1]; they are not taken from any of [2]-[4]. In particular the negative electrode OCP here is not the Chen et al. (2020) LG M50 graphite fit used by LFP.
[1] Faraday Institution BPX standard, `examples/lfp_18650_cell_BPX.json`,
<https://github.com/FaradayInstitution/BPX>
[2] Nyman, A., Behm, M., & Lindbergh, G. (2008). Electrochemical characterisation
and modelling of the mass transport phenomena in LiPF6-EC-EMC electrolyte.
Electrochimica Acta, 53(22), 6356–6365.
<https://doi.org/10.1016/j.electacta.2008.04.023>
[3] O'Regan, K., Brosa Planella, F., Widanage, W. D., & Kendrick, E. (2022).
Thermal-electrochemical parameters of a high energy lithium-ion cylindrical battery.
Electrochimica Acta, 425, 140700.
<https://doi.org/10.1016/j.electacta.2022.140700>
[4] Gerver, R. E., & Meyers, J. P. (2011). Three-dimensional modeling of
electrochemical performance and heat generation of lithium-ion batteries in tabbed
planar configurations. Journal of The Electrochemical Society, 158(7), A835.
<https://doi.org/10.1149/1.3591799>BatteryComponents.MaxwellPC2500 — MethodMaxwellPC2500()EDLC parameters for the 2.5 V Maxwell PC2500 double-layer capacitor, from the measurements [1] reports at NREL's battery thermal management testing facility and ships as the data file of the ultracapacitor block of [2]; the device's own datasheet is [3].
[1] measures capacitance and series resistance on a grid of three temperatures (0, 25 and 40 °C) and six currents (±56.3, ±112.5 and ±225 A), following the test procedure of [4]. An EDLC has one constant of each, so this set takes the 25 °C row at the +112.5 A discharge current, the breakpoint nearest the 100 A rated current of [3]. Across that whole row the measured capacitance spans 2880-2926 F and the resistance 0.890-0.952 mΩ, so the current dependence the single constant drops is under 2% and under 7% respectively. Across all three temperatures it is wider, 2842-2926 F and 0.831-1.182 mΩ; a temperature-dependent series resistance can be passed to EDLCParameters as a (SOC, T) callable if that 42% spread matters.
The measured capacitance sits above the 2700 F ±20% of [3], which is expected: [2] integrates the whole charge of the test including the tapered region rather than the constant-current portion alone, and reports it as a total-charge capacitance. Note also that [1] gives the module mass as 0.71 kg where [3] rates it at 725 g; the heat capacity here uses [1]'s mass and its mean specific heat, 0.71 kg × 1543 J/(kg⋅K).
No "coulombic efficiency" is set, so charge is counted losslessly. [1] does tabulate one over the same (temperature, current) grid, 0.990 to 0.999, but as a two-dimensional table against a current the shared scalar "coulombic efficiency" key has no axis for; the alternative would be to pick one cell of it, which for a 1% effect is not worth the pretence. Set the key yourself if the charge accounting matters more than that.
The stop conditions are 2.5 V to 1.25 V. [1] itself sets its minimum voltage to zero, with a comment that the operating window should be imposed by limiting the state-of-charge range to 0.5-1.0 instead; since SOC = V_oc / V_rated for an EDLC, the half-rated voltage bound here is that same window written once rather than twice.
[1] Tony Markel and Matt Zolot. ESS_UC2_Maxwell.m, "Maxwell PC2500 Ultracapacitor, tested at NREL", National Renewable Energy Laboratory, 1 November 2001.
[2] ADVISOR 2003-00-r0116, Alliance for Sustainable Energy, LLC. https://sourceforge.net/projects/adv-vehicle-sim/
[3] BOOSTCAP Ultracapacitor PC2500 Data Sheet, document 1003992 Rev. 5, Maxwell Technologies. 2700 F ±20%, 2.5 V, 1.0 mΩ DC ±25%, 725 g. https://web.archive.org/web/20060317025924if_/http://www.maxwell.com/pdf/uc/datasheets/PC2500.pdf
[4] Electric Vehicle Capacitor Test Procedure Manual, Revision 0. DOE/ID-10491, Idaho National Engineering Laboratory, October 1994.
BatteryComponents.NCA — MethodNCA()Default parameters for a lithium nickel cobalt aluminum oxide (NCA) cell [1].
[1] Kim, G. H., Smith, K., Lee, K. J., Santhanagopalan, S., & Pesaran, A.
(2011). Multi-domain modeling of lithium-ion batteries encompassing
multi-physics in varied length scales. Journal of The Electrochemical
Society, 158(8), A955-A969. <https://doi.org/10.1149/1.3597614>BatteryComponents.NDCCircuit — MethodNDCCircuit(; name, degradation, capacity, SOC_initial)
NDC topology with supplied element signals: bulk/surface network, a nonlinear terminal voltage source and a series R1-C1 polarization branch; Tian, Fang, Chen and Wang (2020), Figure 1(b) and equations (1a)-(1b). ocv is the nonlinear map h(V_s), evaluated outside this component since it depends on the network's own state rather than on an externally supplied state of charge.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 |
Connectors
capacity_health- This connector represents a real signal as an input to a component ((RealInput))resistance_growth- This connector represents a real signal as an input to a component ((RealInput))p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. ((Pin))n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. ((Pin))ocv- This connector represents a real signal as an input to a component ((RealInput))r0- This connector represents a real signal as an input to a component ((RealInput))r1- This connector represents a real signal as an input to a component ((RealInput))c1- This connector represents a real signal as an input to a component ((RealInput))r_e- This connector represents a real signal as an input to a component ((RealInput))r_c- This connector represents a real signal as an input to a component ((RealInput))c_b- This connector represents a real signal as an input to a component ((RealInput))c_c- This connector represents a real signal as an input to a component ((RealInput))
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
Q_loss | – |
BatteryComponents.NMC — MethodNMC()Default parameters for a lithium nickel manganese cobalt oxide (NMC) cell: an NMC111/graphite 12.5 Ah pouch cell, parameterised by About:Energy Limited (aboutenergy.io) in December 2022 from cell cycling data and post-teardown electrode data, and published as the nmc_pouch_cell_BPX.json example of the Faraday Institution's BPX standard [1].
Every electrode, separator and electrolyte value below, both open-circuit potentials, both entropic coefficients, the activation energies and the voltage bounds match that file. The reaction rate constants are the file's normalised rate constants k [mol/(m²⋅s)] converted to this package's exchange-current prefactor, F k / (c_max √c_e0) with c_e0 = 1000 mol/m³. The capacity and area are those of one of the cell's 34 electrode pairs, both scaled to a 1 m² cross-section.
Not taken from [1]: the electrode and separator thermal properties (thermal conductivity, density, specific heat capacity), which [1] gives only as lumped cell values; these are identical to those of the Marquis2019 set of PyBaMM [5].
The sources [1] itself states:
electrolyte diffusivity and ionic conductivity: [2]; the activation energy of both, 17100 J/mol, is [1]'s
negative electrode entropic coefficient: [3], a fit of up to 3.8e-4 V/K
positive electrode entropic coefficient: [4]
[1] Faraday Institution BPX standard,
examples/nmc_pouch_cell_BPX.json, https://github.com/FaradayInstitution/BPX[2] Nyman, A., Behm, M., & Lindbergh, G. (2008). Electrochemical characterisation and modelling of the mass transport phenomena in LiPF6-EC-EMC electrolyte. Electrochimica Acta, 53(22), 6356–6365. https://doi.org/10.1016/j.electacta.2008.04.023
[3] O'Regan, K., Brosa Planella, F., Widanage, W. D., & Kendrick, E. (2022). Thermal-electrochemical parameters of a high energy lithium-ion cylindrical battery. Electrochimica Acta, 425, 140700. https://doi.org/10.1016/j.electacta.2022.140700
[4] Viswanathan, V. V., Choi, D., Wang, D., Xu, W., Towne, S., Williford, R. E., Zhang, J.-G., Liu, J., & Yang, Z. (2010). Effect of entropy change of lithium intercalation in cathodes and anodes on Li-ion battery thermal management. Journal of Power Sources, 195(11), 3720–3729. https://doi.org/10.1016/j.jpowsour.2009.11.103
[5] Marquis, S. G., Sulzer, V., Timms, R., Please, C. P., & Chapman, S. J. (2019). An asymptotic derivation of a single particle model with electrolyte. Journal of The Electrochemical Society, 166(15), A3693–A3706. https://doi.org/10.1149/2.0341915jes
BatteryComponents.NMC_LiMetal — MethodNMC_LiMetal()Default parameters for an NMC-Li metal cell.
BatteryComponents.PNGVCircuit — MethodPNGVCircuit(; name, degradation, capacity, SOC_initial)
PNGV topology with supplied element signals; ocv is the fixed local linearization voltage.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)r0- This connector represents a real signal as an input to a component (RealInput)r1- This connector represents a real signal as an input to a component (RealInput)c1- This connector represents a real signal as an input to a component (RealInput)c_ocv- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
Q_loss | – |
BatteryComponents.PNGVECM — MethodPNGVECM(; name, degradation, capacity, SOCinitial, U0, R0, R1, C1, Cocv)
PNGV local OCV linearization; U0 is fixed and the drift capacitor accounts for OCV change.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 | |
U0 | – | 3.7 | |
R0 | – | 0.01 | |
R1 | – | 0.01 | |
C1 | – | 1000.0 | |
C_ocv | – | 10000.0 |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)r0- This connector represents a real signal as an input to a component (RealInput)r1- This connector represents a real signal as an input to a component (RealInput)c1- This connector represents a real signal as an input to a component (RealInput)c_ocv- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
Q_loss | – |
BatteryComponents.PackAmbient — MethodPackAmbient(; name, series, temperature, conductance)
Convective boundary applied independently to every series row of an array pack.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
series | – | 1 | |
temperature | – | fill(298.15, series, 1) | |
conductance | – | 1.0 |
Connectors
port- Thermal boundary for a battery pack, with one independent temperature and inward heat flow per series row. (ArrayHeatPort)
BatteryComponents.PackForcedAir — MethodPackForcedAir(; name, cooling = ForcedAirCooling(), temperature = 298.15,
series = nothing, parallel = nothing, nodes = nothing, conductance = 1.0)A forced-air convective boundary for a battery pack: massless case nodes, cooling air, and a thermostat-controlled fan. It is the third thermal boundary next to PackAmbient (a fixed-coefficient convection per series row) and the ideal coolant temperature a PackThermalNetwork drains into by default, and CyclingCircuit selects it with cooling = ForcedAirCooling(...). The model is the single-node thermal model of ADVISOR 2003 (NREL, ess_therm), with its correlations as the shipped defaults of ForcedAirCooling and every number a parameter.
With series = nothing the boundary has a port, scalar for one node and shaped (nodes, 1) for a chain, for the heatport_coolant of a networked pack. The case temperature is the port temperature: the network already holds the conductances from each exposed cell face to it. With series = S it has the two row ports port_left and port_right of an array pack, each row face reaching the case node through conductance [W/K] as it reaches the ambient of a PackAmbient. The thermostat reads the real input T_sense, which CyclingCircuit wires to the pack's hottest cell temperature T; a hand-built circuit must connect it.
Heat leaves the case node through the case wall and the air film in series,
Q_case = (T_case - T_air) / R_eff, R_eff = t / (k A) + 1 / (h A),
h = h_reference (v / velocity_reference)^velocity_exponent (fan on), h_natural (fan off),
v = fan_flow / (air_density * flow_area),For nodes = 1, the air node carries the energy balance of a mean-air volume with a through flow ṁ (fan_flow with the fan on, natural_flow with it off). The module sees the mean of the inlet and the outlet air, T_air = (temperature + T_out) / 2, which is the source's statement that half of the rejected heat goes into warming the air:
air_mass * c_p * dT_air/dt = Q_case - Q_out, Q_out = ṁ c_p (T_out - temperature),
T_out = 2 T_air - temperature.With air_mass = 0 (the default) the left-hand side vanishes and the air is quasi-steady, T_air = temperature + Q_case / (2 ṁ c_p), exactly the source's relation; the heat that leaves the cells then leaves with the flow at every instant, and with a positive air_mass part of it is stored in the air first. Both are reported as Q_case and Q_out, with T_out the exhaust temperature.
For a directional cooling.flow_axis, CyclingCircuit sets nodes to the selected pack dimension. In a manually wired boundary, nodes defaults to that dimension when series is provided, and to 1 otherwise. Parallel-axis row-port geometry requires an explicit parallel dimension. A chain with N > 1 has (N, 1) fields T_case, T_air and Q_case; these fields are scalar for N = 1. The (N, 1) field T_exit holds the outlet temperature of each slice for every node count. The case sees the midpoint of its inlet and outlet:
T_air,k = (T_exit,k-1 + T_exit,k) / 2,
(air_mass / N) c_p dT_air,k/dt = Q_case,k + ṁ c_p (T_exit,k-1 - T_exit,k),
T_exit,0 = T_inlet, T_out = T_exit,N, Q_out = ṁ c_p (T_out - T_inlet).The case wall and film use area / N per node. With zero air mass each node satisfies its algebraic advective balance. With positive air mass the midpoint temperatures T_air are the states, set through T_air in u0, and each outlet temperature follows from its inlet by the midpoint relation. With one node these equations give the ADVISOR relation above, including its positive-mass time constant air_mass / (2 ṁ). Uniform steady heating gives a mean case-seen air rise of sum(Q_case) / (2 ṁ c_p) for every node count.
With per-row ports, series flow couples both faces of row k to case k, and multi-node parallel flow is rejected because the ports reach only the end columns. A network preserves its exposed-face geometry and assigns each exposed face the case temperature of its slice. CyclingCircuit rejects network geometries that leave a slice without an exposed face: multi-node parallel flow needs positive coolant_conductance_lateral, or positive coolant_conductance with at most two columns, and multi-node series flow needs positive coolant_conductance, or positive coolant_conductance_lateral with at most two rows. A hand-wired BatteryPack(; thermal_network, coolant_axis) connected to PackForcedAir(; nodes) is not checked: each node receives area / N, and the case area of a slice with no exposed face is lost.
The fan is a discrete variable fan_on, 1 or 0, switched by two continuous events: it turns on when T_sense rises through T_set and off when it falls through T_set - hysteresis. It is an event rather than a smooth switch because a fan is either running or not, and a smoothed step would leave the fan half on and the film coefficient in between whenever the temperature sits near the setpoint. Its initial value is solved with the initial state, on when the pack starts at or above T_set. After every switch the DAE is re-initialized and the integrator's proposed step is capped, as Cycler does, so the jump in h is not carried across a large step. Read the fan state from a solution through h or air_flow at chosen times, sol(t; idxs = cooler.h): they depend on the discrete alone, so sol[cooler.h] holds one value per switch rather than one per saved time.
Limitations
The case has no thermal mass, radiation is not separated from convection, and the fan has a single speed. The thermostat is ideal: no sensor lag, and no minimum run time beyond what hysteresis imposes. With zero air mass, T_exit overshoots the case temperature and oscillates along the chain when the per-node case-to-air conductance, wall and film in series, exceeds 2 ṁ c_p, for example under natural_flow with a large area.
BatteryComponents.PlettE2 — MethodPlettE2()Plett's E2 ESC parameter set at 25 °C, transcribed from ESCEKF/E2model.mat in his companion archive. The field names and units are specified in ECE5710 Notes 02, p. 2–29 (unnumbered table); the simulation on p. 2–27 uses this model and E2_DYN_35_P25.mat. The OCV values are OCV0 + 25 * OCVrel on the published 201-point SOC grid. The one RC capacitance is derived as RCParam / RParam.
This is a single-temperature fit, with no extrapolation claim to other cell temperatures. The archive's -25 °C coulombic efficiency is the printed/stored negative value -1.3799220052869889; it is not part of this 25 °C set and is not silently corrected. Voltage/SOC stop bounds are simulation limits, not an independently sourced manufacturer rating. No thermal parameters are supplied.
Sources:
- https://mocha-java.uccs.edu/ECE5710/ECE5710-Notes02.pdf, pp. 2–27–2–29.
- http://mocha-java.uccs.edu/BMS2/CH3/ESCEKF.zip,
ESCEKF/E2model.mat, 25 °C row. SHA256 of the MAT file:0593437188a1eba441522b7da554c8c760e0b832a28508bc4525cf8f9278ce53.
BatteryComponents.RandlesCapacitor — MethodRandlesCapacitor(; name, U_initial)
Series capacitor with an initial voltage; positive current raises U.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
U_initial | – | 0.0 |
Connectors
I- This connector represents a real signal as an input to a component (RealInput)C- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
U | – |
BatteryComponents.RandlesCircuit — MethodRandlesCircuit(; name, degradation, doublelayer, diffusion, ndl, nd, capacity, SOCinitial, vdlinitial, fdllow, fdlhigh, fdlow, fdhigh)
Randles circuit with supplied element signals: OCV and Rs in series with a double layer in parallel with Rct and a diffusion element. Finite-length Warburgs use nd Foster modes and a static remainder; CPEs use an n-branch RC ladder over [flow, f_high] Hz with tail elements.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
double_layer | – | RandlesDoub...Capacitor() | |
diffusion | – | RandlesDiff...nsmissive() | |
n_dl | – | 0 | |
n_d | – | 8 | |
n_w | – | ifelse(__dy...e), 0, n_d) | |
n_cpe | – | nd - nw | |
reflective | – | __dyadisa...Reflective) | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 | |
v_dl_initial | – | 0.0 | |
f_dl_low | – | 1e-3 | |
f_dl_high | – | 1e3 | |
f_d_low | – | 1e-3 | |
f_d_high | – | 1e3 |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)r_s- This connector represents a real signal as an input to a component (RealInput)r_ct- This connector represents a real signal as an input to a component (RealInput)c_dl- This connector represents a real signal as an input to a component (RealInput)q_dl- This connector represents a real signal as an input to a component (RealInput)alpha_dl- This connector represents a real signal as an input to a component (RealInput)r_d- This connector represents a real signal as an input to a component (RealInput)tau_d- This connector represents a real signal as an input to a component (RealInput)q_d- This connector represents a real signal as an input to a component (RealInput)alpha_d- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
U_dl | – | |
U_d | – | |
R_modes | – | |
losses_dl | – | |
losses_d | – | |
Q_loss | – | |
Q_dl | – | |
i_f | – | |
v_dl | – |
BatteryComponents.RandlesTerminal — MethodRandlesTerminal(; name)
Randles junction and terminal: double-layer and faradaic arms in parallel, each a series resistance R and a stored voltage E, behind R_s; discharge-positive I.
Connectors
I- This connector represents a real signal as an input to a component (RealInput)OCV- This connector represents a real signal as an input to a component (RealInput)R_s- This connector represents a real signal as an input to a component (RealInput)R_dl- This connector represents a real signal as an input to a component (RealInput)E_dl- This connector represents a real signal as an input to a component (RealInput)R_f- This connector represents a real signal as an input to a component (RealInput)E_f- This connector represents a real signal as an input to a component (RealInput)V- This connector represents a real signal as an output from a component (RealOutput)i_f- This connector represents a real signal as an output from a component (RealOutput)i_dl- This connector represents a real signal as an output from a component (RealOutput)v_dl- This connector represents a real signal as an output from a component (RealOutput)Q- This connector represents a real signal as an output from a component (RealOutput)
BatteryComponents.RintCircuit — MethodRintCircuit(; name, degradation, capacity, SOC_initial)
Rint topology with a supplied OCV and resistance signal.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)r0- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
Q_loss | – |
BatteryComponents.RintECM — MethodRintECM(; name, degradation, capacity, SOC_initial, R0)
Rint cell with constant series resistance; He et al. (2011), equation (1).
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 | |
R0 | – | 0.01 |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)r0- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
Q_loss | – |
BatteryComponents.SaftHighPower12Ah — MethodSaftHighPower12Ah()RCModel parameters for the 12 A⋅h high-power lithium-ion cell of Saft America: the five elements of Saft's own two-capacitance model of that cell as figure 3 of [1] prints them, R_e = 1.1 mΩ, R_c = 0.4 mΩ, R_t = 1.2 mΩ, C_b = 82 kF and C_c = 4.074 kF. [1] translated the model from P-Spice into the RC block of the ADVISOR vehicle simulator and verified the translation on a single 18 s, 200 A discharge pulse (its figure 4): the voltage begins at 3.86 V, drops to 3.561 V at 0 s, falls further to 3.386 V after 18 s, and recovers to a steady state of 3.818 V after 100 s. test/ecm_bulk_surface.jl replays that pulse through RCModel and asserts those four voltages, so this set doubles as the published regression check of the bulk/surface circuit. With the elements as printed, the circuit gives 3.5613 V at the onset and 3.8182 V after recovery, on the printed digits, and 3.3847 V at the end of the pulse, 1.3 mV below the printed 3.386 V. The difference is inside the precision the elements are printed to: R_e = 1.0922 mΩ, which prints as 1.1 mΩ, puts all three voltages on their printed digits. The set keeps the printed values.
The "open-circuit voltage" is the constant 3.86 V of that run. [1] shows the cell's open-circuit voltage against state of charge only as a plot (its figure 6, for the 6 A⋅h cell of the same construction), so there is no curve to transcribe, and the constant does one thing: it sets U_b and U_c at t = 0 to the rest voltage of the verification pulse. Consequences: the state of charge is coulomb-counted against the 12 A⋅h nominal capacity from the default initial state of charge of one, since [1] states none for the pulse; the set cannot be used with RCModel(; soc = :capacitor), which needs a curve to invert and rejects the constant; and the rest voltage carries no state-of-charge dependence beyond what the two capacitors accumulate. Replace the entry by a measured curve before using the set for anything but the circuit's pulse response.
No bounds are set, as [1] gives no cut-off voltages, currents or temperatures for this cell; its nominal voltage is stated as 3.6 V. The elements are constants: [1] reports that Saft supplied the bulk capacitance as a function of temperature and the bulk impedance as a function of state of charge and temperature, but tabulates neither. temperature = true needs a "heat capacity", which [1] does not report.
For the model's accuracy against a cell rather than against P-Spice, [1] runs a 600 s US06-derived power profile on a three-cell module and finds the RC model within 1.2% average (0.7% standard deviation) and 5% maximum terminal-voltage error; that module was built from the 6 A⋅h cells, so the figure is for the RC model, not for this parameter set.
[1] Valerie H. Johnson, Ahmad A. Pesaran and Thomas Sack. "Temperature-Dependent Battery Models for High-Power Lithium-Ion Batteries." 17th Electric Vehicle Symposium (EVS-17), Montreal, 15-18 October 2000. NREL/CP-540-28716. https://www.nrel.gov/docs/fy01osti/28716.pdf
BatteryComponents.SaftLiIon6Ah — MethodSaftLiIon6Ah()Rint parameters for the Saft 6 A⋅h high-power lithium-ion cell tested at NREL in 1999 [1], as gridded LookupTables over the state of charge (0, 10, 20, 40, 60, 80 and 100 %) and the cell temperature (0, 25 and 41 °C): the open-circuit voltage, a separate discharge and charge resistance, the capacity and the coulombic efficiency, the last two against temperature alone. It is the Rint-format battery data file of ADVISOR [2] that the model's published accuracy figures were established on — 3 % average and 12 % maximum voltage error over US06-derived cycles [1] — and it exercises every entry the temperature-dependent Rint model has:
| file variable | entry |
|---|---|
ess_voc | "open-circuit voltage", (SOC, T) table |
ess_r_dis | "discharge resistance", (SOC, T) table |
ess_r_chg | "charge resistance", (SOC, T) table |
ess_max_ah_cap | "nominal capacity", T table [A⋅h] |
ess_coulombic_eff | "coulombic efficiency", T table |
The data file describes a three-cell module and multiplies every per-cell table by three; this set is the cell, i.e. the tables as printed before that factor, with the voltage window 2.0–3.9 V and a heat capacity of 0.37824 kg × 795 J/(kg⋅K) = 300.7 J/K from the file's module mass and specific heat. The tables were built by NREL's batmodel tool from capacity, open-circuit-voltage and resistance tests on cell 72 at 0, 20 and 40 °C in May and July 1999; the file itself places its temperature breakpoints at 0, 25 and 41 °C, and those are what is transcribed here. The capacity is the C/3 capacity. The file sets no initial state of charge (ADVISOR takes it from the vehicle file), so this set starts full.
The temperature dependence is only active in a cell built with temperature = true; the isothermal default evaluates every table at the "initial temperature", 25 °C.
The set is provided under the licence of [2], reproduced beside the data in the source; the tables are the measurements as published there and nothing has been refitted.
[1] Valerie H. Johnson. "Battery performance models in ADVISOR." Journal of Power Sources 110, no. 2 (2002): 321-329. https://doi.org/10.1016/S0378-7753(02)00194-5
[2] Valerie H. Johnson. ESS_LI7_temp.m, "6 Ah Saft Lithium Ion battery", National Renewable Energy Laboratory, 12 April 2000, released as non-proprietary by Saft 30 May 2000. In ADVISOR 2003-00-r0116, Alliance for Sustainable Energy, LLC, https://sourceforge.net/projects/adv-vehicle-sim/ (advisor/data/energy_storage/).
BatteryComponents.TheveninCircuit — MethodTheveninCircuit(; name, degradation, nrc, capacity, SOCinitial)
N-RC topology with supplied element signals, allowing SOC and temperature dependent maps.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
n_rc | – | 1 | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)r0- This connector represents a real signal as an input to a component (RealInput)r- This connector represents a real signal as an input to a component (RealInput)c- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
U | – | |
losses | – | |
Q_loss | – |
BatteryComponents.TheveninECM — MethodTheveninECM(; name, degradation, nrc, capacity, SOCinitial, R0, R, C)
N-RC Thevenin cell with constant elements; He et al. (2011), equations (3) and (5).
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
degradation | – | ECMDegradat...gradation() | |
n_rc | – | 1 | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 | |
R0 | – | 0.01 | |
R | – | fill(0.01, n_rc) | |
C | – | fill(1000.0, n_rc) |
Connectors
capacity_health- This connector represents a real signal as an input to a component (RealInput)resistance_growth- This connector represents a real signal as an input to a component (RealInput)p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)ocv- This connector represents a real signal as an input to a component (RealInput)r0- This connector represents a real signal as an input to a component (RealInput)r- This connector represents a real signal as an input to a component (RealInput)c- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
SOH | – | |
resistance_factor | – | |
I | – | |
V | – | |
SOC | – | |
U | – | |
losses | – | |
Q_loss | – |
BatteryComponents.Tian2020NCR18650B — MethodTian2020NCR18650B()The nonlinear double-capacitor (NDC) fit of a Panasonic NCR18650B cell (3.2 V–4.2 V), identified by parameter identification 1.0 (constant-current charging/discharging). Tian, Fang, Chen and Wang, "Nonlinear Double-Capacitor Model for Rechargeable Batteries: Modeling, Identification and Validation," IEEE Transactions on Control Systems Technology, 2020 (arXiv:1906.04150, MERL TR2020-035).
"nominal capacity"and"open-circuit voltage": Section V-A, p. 9. Coulomb counting givesQ_t = 3.06A⋅h; the fittedh(·)readsOCV = 3.2 + 2.59·SoC - 9.003·SoC² + 18.87·SoC³ - 17.82·SoC⁴ + 6.325·SoC⁵."bulk capacitance","surface capacitance","end resistance","capacitor resistance","polarization resistance"and"polarization capacitance": Section V-A, p. 9, the physical parameter estimates reconstructed from Table II via the Section III-B formulas —C_b = 10037F,C_s = 973F,R_b = 0.019Ω,R_1 = 0.02Ω,C_1 = 3250F.R_sis assumed zero, following the paper's own recommendation from [59] (R_s ≪ R_b, Section III-B); it is a modeling assumption of the source, not a value this package supplies."series resistance": Section V-A, pp. 9–10,R_0 = γ₁ + γ₂ e^{-γ₃·SoC} + γ₄ e^{-γ₅(1-SoC)}(the form of equation (4)) with the identifiedθ̂row of Table II, p. 10:γ = (0.0531, 0.1077, 3.807, 0.0533, 7.613).
The paper's own text states C_b + C_s = 11,011 F, one more than 10037 + 973 = 11010; both printed values are kept as published rather than adjusted to agree; the one-farad gap is far smaller than the parameter identification's own reported tolerance and does not by itself indicate which of C_b, C_s or the stated sum is in error.
No temperature dependence is reported for this fit — the paper's experiments are not described as spanning multiple temperatures — so every entry here is temperature independent and the model's default 298.15 K initial temperature is a package default, not a value measured in the source.
The source's raw experimental records (its Figures 6–12) are not published data files, only plots; this set can be checked against the paper's closed-form equations and against qualitative descriptions of those figures, not against the measured voltage traces themselves.
BatteryComponents.TremblayDessaint2009 — MethodTremblayDessaint2009(; battery_type = :lithium_ion)Table 1 parameters from Tremblay and Dessaint (2009), https://doi.org/10.3390/wevj3020289, for TremblayDessaint. battery_type is :lithium_ion, :lead_acid, :nimh or :nicd. The two polarization coefficients have the table's numerical K, with units V/Ah and ohm. The filter time constant is 30 s (section 3), not a 95% response time.
Capacity follows the column headings (2.3 Ah Li-ion/NiCd and 7.2 Ah lead-acid), except NiMH: section 4.1 explicitly identifies its maximum capacity as 7 Ah although Table 1 labels the cell 6.5 Ah. Both numbers are preserved here in their stated roles; the nominal-voltage/current data for that replay are 1.2 V and 1.3 A. The SOC denominator uses the maximum capacity, as the equations require.
Initial SOC is one and filtered current is zero. The exponential-memory state's default follows the discharged-from-full solution A*exp(-B*Q*(1-SOC_initial)), which is A at this SOC of one. Default SOC stop limits are 0.2–1 (0.3–1 for lead-acid), the validity ranges in section 4.2. These are empirical, isothermal parameters, not a heat model or held-out experimental validation. The charging-law interpretation is documented in TremblayDessaint.
BatteryComponents.TremblayDessaintECM — MethodTremblayDessaintECM(; name, exponentialmemory, nickel, capacity, SOCinitial, E0, R0, Kq, Ki, A, B, tau, Iinitial, Expinitial)
Electrical Tremblay–Dessaint cell in seconds and Ah. The empirical law is TremblayDessaintLaw; only the series resistor contributes to Q_loss.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
exponential_memory | – | false | |
nickel | – | false | |
capacity | – | 1.0 | |
SOC_initial | – | 1.0 | |
E0 | – | 3.366 | |
R0 | – | 0.01 | |
Kq | – | 0.0076 | |
Ki | – | 0.0076 | |
A | – | 0.26422 | |
B | – | 26.5487 | |
tau | – | 30.0 | |
I_initial | – | 0.0 | |
Exp_initial | – | A * exp(-B ...C_initial)) |
Connectors
p- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)n- This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)
Variables
| Name | Description | Units |
|---|---|---|
I | – | |
V | – | |
SOC | – | |
SOH | – | |
ocv | – | |
Q_loss | – |
BatteryComponents.TremblayDessaintLaw — MethodTremblayDessaintLaw(; name, exponentialmemory, nickel, E0, R0, Kq, Ki, A, B, tau, Iinitial, Exp_initial)
Tremblay–Dessaint empirical voltage law. Charge uses Q/(q+0.1Q), with its branch selected by filtered current. Q and q are in Ah, current in A, and time in seconds.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
exponential_memory | – | false | |
nickel | – | false | |
E0 | – | 3.366 | |
R0 | – | 0.01 | |
Kq | – | 0.0076 | |
Ki | – | 0.0076 | |
A | – | 0.26422 | |
B | – | 26.5487 | |
tau | – | 30.0 | |
I_initial | – | 0.0 | |
Exp_initial | – | A |
Connectors
I- This connector represents a real signal as an input to a component (RealInput)SOC- This connector represents a real signal as an input to a component (RealInput)Q- This connector represents a real signal as an input to a component (RealInput)V- This connector represents a real signal as an output from a component (RealOutput)OCV- This connector represents a real signal as an output from a component (RealOutput)
Variables
| Name | Description | Units |
|---|---|---|
q_extracted | – | |
I_filtered | – | |
exponential_voltage | – |
BatteryComponents.Vandeputte2023 — MethodVandeputte2023(; open_circuit_voltage, nominal_capacity)The Randles impedance simulated in Section 6 of Vandeputte et al. [1], for Randles(; diffusion = :cpe): R_S = 551 mΩ, R_CT = 119 mΩ, C_DL = 1464 mF and the semi-infinite Warburg coefficient σ = 0.0346 Ω/√s, which [1] takes from Islam et al. (2018). The Warburg element of [1], eq. (9), Z_W = σ√2/√(jω), is stored as the CPE it is, with exponent 1/2 and coefficient 1/(σ√2) F⋅s^(-1/2).
The CPE realization band is [5e-5, 1e4] Hz. [1] simulates P = 5 periods of T_p = 200 s sampled at f_s = 200 Hz, so its excited band is at most [1/T_p, f_s/2] = [5 mHz, 100 Hz]; the realization band extends two decades beyond that on each side, which puts the simulated band inside the realization's accurate band (see Randles). That accuracy needs at least 17 branches, two per decade; the default Randles(; diffusion = :cpe) has 24.
Section 6 specifies the impedance only, so the open-circuit voltage and the capacity are required keywords: open_circuit_voltage [V] is a constant, or any "open-circuit voltage" entry EquivalentCircuitParameters accepts, and nominal_capacity is in A⋅h. Neither enters the impedance.
[1] Freja Vandeputte, Noël Hallemans, Jishnu Ayyangatu Kuzhiyil, Nessa Fereshteh Saniee, Widanalage Dhammika Widanage and John Lataire. "Frequency domain parametric estimation of fractional order impedance models for Li-ion batteries." arXiv:2305.15840 (2023), Section 6 and eqs. (9), (11). https://arxiv.org/abs/2305.15840
BatteryComponents.WarburgMode — MethodWarburgMode(; name, reflective)
Foster mode k of a finite-length Warburg impedance Rd tanh(z)/z (transmissive) or Rd coth(z)/z (reflective), z = sqrt(s tau): the partial fractions 2 R_d / (lambda^2 + s tau) of DLMF 4.36.2-4.36.3.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
reflective | – | false |
Connectors
R_d- This connector represents a real signal as an input to a component (RealInput)tau- This connector represents a real signal as an input to a component (RealInput)k- This connector represents a real signal as an input to a component (RealInput)R- This connector represents a real signal as an output from a component (RealOutput)C- This connector represents a real signal as an output from a component (RealOutput)
BatteryComponents.WarburgRemainder — MethodWarburgRemainder(; name, reflective)
Static remainder of a finite-length Warburg truncated to modes with total resistance Rmodes, and the reflective series capacitance tau / Rd.
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
reflective | – | false |
Connectors
R_d- This connector represents a real signal as an input to a component (RealInput)tau- This connector represents a real signal as an input to a component (RealInput)R_modes- This connector represents a real signal as an input to a component (RealInput)R- This connector represents a real signal as an output from a component (RealOutput)C- This connector represents a real signal as an output from a component (RealOutput)
BatteryComponents.aluminum_current_collector — Methodaluminum_current_collector()Default parameters for an aluminum current collector.
BatteryComponents.calibrate_rc — Functioncalibrate_rc(pulses; alg = SingleShooting(maxiters = 300), capacitance = nothing,
capacitance_ratio = nothing, guesses = rc_initial_guess.(pulses), spread = 100,
reltol = 1e-8, abstol = 1e-10)
calibrate_rc(pulse::HPPCPulse; kwargs...)Calibrate the RCModel to each of pulses (HPPCPulses, from hppc_pulses) with DyadModelOptimizer, the third step of ADVISOR's HPPC processing [1]: each pulse becomes an Experiment of the package's RC cell (build_ecm_cell) driven by the pulse's measured current, interpolated linearly between its samples, with its measured voltage as the data, and an InverseProblem over the cell's impedance that calibrate solves with alg, a DyadModelOptimizer calibration algorithm (only the default SingleShooting is tested). Returns one RCFit per pulse, whose circuit is the five elements in the parameter-set format and which rc_tables tabulates over the state of charge and the temperature.
Requires using DyadModelOptimizer, a JuliaHub package, which loads this method as a package extension.
The replay starts with both capacitors at the rest voltage before the pulse, so a pulse has to start from a relaxed cell. The regenerative pulse of a PNGV HPPC profile follows the discharge pulse after only 40 s, before a cell with a slow time constant has relaxed; an entry of pulses may instead be a vector of consecutive pulses, such as [discharge, regen], which is calibrated as one record from the rest before the first — ADVISOR's window, from the start of its 18 s pulse to the end of the charge pulse after it. A pulse's rest_before tells the two cases apart.
The pulse does not determine all five elements. The RC circuit — R_t in series with two series-RC branches in parallel — has the terminal impedance
Z(s) = R_0 + 1 / (C s) + A / (1 + τ s),
C = C_b + C_c, τ = (R_e + R_c) C_b C_c / C,
R_0 = R_t + R_e R_c / (R_e + R_c), A = (C_b R_e - C_c R_c)² / (C² (R_e + R_c))which is the impedance of the PNGV model with C_ocv = C, R_1 = A and C_1 = τ / A. A current and voltage record therefore fixes these four groups and no more, and τ only when A > 0: a circuit with C_b R_e = C_c R_c has no polarization term, and the calibration, which searches A in its logarithm, takes A > 0 (a guess with A = 0 is an error). There is a one-parameter family of element sets with identical terminal behaviour, which the ratio C_b / C_c labels. At one ratio there are two element sets with the impedance, the two roots of a quadratic: one with the bulk branch the slower, C_b R_e ≥ C_c R_c, and one with the surface branch the slower, which is the same circuit as a set of the first kind at the ratio 1 / ρ with the two branches' names exchanged.
The calibration therefore searches the four groups, each in its logarithm, and writes the cell's elements as the closed-form set of the first kind at a ratio ρ given by a rule: by default the geometric midpoint of the range of ratios for which that set is positive (below the range R_c would be negative, above it R_t), itself an expression of the groups — the member of the family furthest from both degenerate ends. Every impedance with A > 0 is therefore reachable, the voltage depends on the searched groups alone, which the record determines, and the elements are unique given the rule; the set whose surface branch is the slower has no expression in the search. Pass a number as capacitance_ratio to take every pulse's elements at that ratio instead, or a vector to give each its own (ADVISOR's RC block weights its capacitor states of charge 20:1, the ratio of the cell it was written for, SaftHighPower12Ah); a ratio outside the range the calibrated impedance admits is an error, since some element would be negative, and a circuit whose surface branch is the slower is calibrated at the reciprocal ratio with the names exchanged. The range is reported in each fit. The ratio changes no terminal voltage, only how the dissipation divides between the three resistors and the state of charge that RCModel(; soc = :capacitor) reads back. ADVISOR's optimizer searches ±10% around an initial guess of the five elements instead, which fixes the ratio near the guess's without saying so.
capacitance [F], a number or one per pulse, fixes the total capacitance C = C_b + C_c as well, leaving R_0, A and τ to calibrate. A pulse determines C through the shift of the rest voltage by the charge it drew, q / C, which for a large cell is a fraction of a millivolt and below the resolution of most records. The charge the cell stores fixes it instead, C = 3600 Q / (dOCV/dSOC) at the pulse's state of charge for a capacity Q [A⋅h] — which is also what makes the capacitors hold the cell's capacity, as RCModel(; soc = :capacitor) assumes — and ADVISOR's bulk capacitance from the rated energy is the same idea over the whole voltage window:
slope(p) = (ocv(p.soc_before + 0.05, T) - ocv(p.soc_before - 0.05, T)) / 0.1
fits = calibrate_rc(pulses; capacitance = [3600 * Q / slope(p) for p in pulses])Each searched group is bounded to a factor spread either side of its value in the initial guess and searched in its logarithm. guesses are (; R_0, A, τ, C) starting points, one per pulse, as rc_initial_guess returns them. reltol and abstol are the tolerances of the replay (FBDF, stepping to every sample). The replay resolves the branch currents of a milliohm cell only to about 3e-13 A, so an abstol far below the default 1e-10 makes FBDF fail on that roundoff at points of the search, and a failed replay ends the calibration there. The calibration minimizes the squared voltage error over the samples; ADVISOR minimizes the mean absolute percentage error of a replay of the measured power, since its battery blocks take a power request where the package's cells take a current. The source of the recipe is ADVISOR's code, since the EVS-18 paper describing it [2] was not available.
[1] ADVISOR 2003-00-r0116, extras/batmodel/process_HPPC.m, Alliance for Sustainable Energy, LLC. https://sourceforge.net/projects/adv-vehicle-sim/
[2] Valerie H. Johnson, Matthew Zolot and Ahmad Pesaran. "Development and validation of a temperature-dependent resistance/capacitance battery model for ADVISOR." 18th Electric Vehicle Symposium (EVS-18), Berlin, October 2001. NREL/CP-540-31363.
BatteryComponents.capacity_cell — Methodcapacity_cell(cell)The capacity of one cell [A⋅h], from the parameters of a BatteryCell, BatteryPack or CyclingCircuit component. It is the value the cell variable cell_capacity takes, i.e. the chemistry's nominal capacity where it defines one and the theoretical capacity otherwise.
BatteryComponents.capacity_pack — Methodcapacity_pack(pack)The capacity of a BatteryPack or CyclingCircuit component [A⋅h]: the cell capacity times the number of cells in parallel, the value of the pack variable Q. It converts the C-rates of a cycling protocol, so charge(1C) on the pack is charge(capacity_pack(pack)) amperes.
BatteryComponents.cell_views — Methodcell_views(pack)Return a series × parallel matrix of CellViews for an array pack or a circuit containing one. For example, cell_views(pack)[2, 3].SOC indexes the state of charge of cell (2, 3). The views share the pack's array fields.
BatteryComponents.charge — Methodcharge(input; time, bounds)Setup for a charge experiment.
Arguments:
input: Current input with units ofAorC(C-rate) or power input with units ofW.time: Optional argument to set a maximum experiment time.bounds: Optional experiment-specific stop conditions, e.g.bounds = (V_max = 4.2,)orbounds = :V_max => 4.2, overriding the defaults of theCycler(seedefault_bounds);bounds = falsedisables all stop conditions for this experiment.
BatteryComponents.charge_current — Methodcharge_current(input; time, bounds)Setup for a current experiment to charge the battery.
Arguments:
input: Current input with units ofAorC(C-rate).time: Optional argument to set a maximum experiment time.bounds: Optional experiment-specific stop conditions, e.g.bounds = (V_max = 4.2,)orbounds = :V_max => 4.2, overriding the defaults of theCycler(seedefault_bounds);bounds = falsedisables all stop conditions for this experiment.
BatteryComponents.charge_power — Methodcharge_power(input; time, bounds)Setup for a power experiment to charge the battery.
Arguments:
input: Power input with units ofW.time: Optional argument to set a maximum experiment time.bounds: Optional experiment-specific stop conditions, e.g.bounds = (V_max = 4.2,)orbounds = :V_max => 4.2, overriding the defaults of theCycler(seedefault_bounds);bounds = falsedisables all stop conditions for this experiment.
BatteryComponents.copper_current_collector — Methodcopper_current_collector()Default parameters for a copper current collector.
BatteryComponents.current — Methodcurrent(input; time, bounds)Setup for a current experiment. By convention, positive current is discharging and negative current is charging.
Arguments:
input: Current input with units ofAorC(C-rate).time: Optional argument to set a maximum experiment time.bounds: Optional experiment-specific stop conditions, e.g.bounds = (V_max = 4.2,)orbounds = :V_max => 4.2, overriding the defaults of theCycler(seedefault_bounds);bounds = falsedisables all stop conditions for this experiment.
BatteryComponents.default_bounds — Methoddefault_bounds(battery)The default stop conditions of a BatteryCell, BatteryPack or CyclingCircuit component, as a NamedTuple of I_min, I_max, V_min, V_max, P_min, P_max, T_min, T_max, SOC_min and SOC_max: the chemistry's own bounds, scaled to the pack (voltages add in series, currents in parallel). A bound the chemistry does not define is NaN, i.e. disabled. They are what CyclingCircuit gives its Cycler unless its bounds keyword overrides them.
BatteryComponents.default_parameters — Methoddefault_parameters(model)The parameter set BatteryCell, BatteryPack and CyclingCircuit use for model when no chemistry is given: NMC for the electrochemical models, and for the equivalent circuit models the published set that covers the topology — ChenRinconMora2006 for Rint, Thevenin(2) and DP, He2011LiMn2O4 for first-order Thevenin, PNGV and RCModel, which are covered by its model-specific parameter fits, and MaxwellPC2500 for EDLC, TremblayDessaint2009 for TremblayDessaint, matching its battery type. Randles has none, since its published set, Vandeputte2023, does not give an open-circuit voltage or a capacity.
BatteryComponents.discharge — Methoddischarge(input; time, bounds)Setup for a discharge experiment.
Arguments:
input: Current input with units ofAorC(C-rate) or power input with units ofW.time: Optional argument to set a maximum experiment time.bounds: Optional experiment-specific stop conditions, e.g.bounds = (V_max = 4.2,)orbounds = :V_max => 4.2, overriding the defaults of theCycler(seedefault_bounds);bounds = falsedisables all stop conditions for this experiment.
BatteryComponents.discharge_current — Methoddischarge_current(input; time, bounds)Setup for a current experiment to discharge the battery.
Arguments:
input: Current input with units ofAorC(C-rate).time: Optional argument to set a maximum experiment time.bounds: Optional experiment-specific stop conditions, e.g.bounds = (V_max = 4.2,)orbounds = :V_max => 4.2, overriding the defaults of theCycler(seedefault_bounds);bounds = falsedisables all stop conditions for this experiment.
BatteryComponents.discharge_power — Methoddischarge_power(input; time, bounds)Setup for a power experiment to discharge the battery.
Arguments:
input: Power input with units ofW.time: Optional argument to set a maximum experiment time.bounds: Optional experiment-specific stop conditions, e.g.bounds = (V_max = 4.2,)orbounds = :V_max => 4.2, overriding the defaults of theCycler(seedefault_bounds);bounds = falsedisables all stop conditions for this experiment.
BatteryComponents.experiment_results — Methodexperiment_results(sol, state, SOC)The ExperimentResults of a solution sol of a circuit driven by a Cycler: one per step of the protocol that ran, in order, with the reason that ended it, the indices it covers in the solution and the cycle it belongs to. state is the CyclerState the cycler logged into and SOC the state of charge over the solution (sol[circuit.SOC]), which tells a charge from a discharge where the step itself does not say.
state = CyclerState()
@named circuit = CyclingCircuit(; protocol = [charge(1C), voltage(hold)], state)
sys = mtkcompile(circuit)
prob = ODEProblem(sys, [], (0.0, 1e5))
sol = solve(prob, FBDF())
results = experiment_results(sol, state, sol[sys.SOC])
[e.exit_reason for e in results]Steps that were skipped because their stop conditions were already met are in state.log but are not results. The cycler appends to the log, so empty!(state.log) before solving the same problem a second time.
BatteryComponents.find_variables — Methodfind_variables(cell, description)The variables of a cell component (see BatteryCell, or one of cell_views) whose description metadata is description, ordered by their grid index. Variables discretized along the cell are addressed one grid point at a time and their descriptions are qualified with the section, so "negative electrode particle concentration" returns the particles of the negative electrode and the unqualified "electrolyte concentration" returns the electrolyte concentration of every section. Parameters are qualified likewise ("negative electrode thickness").
BatteryComponents.gridvariables — Methodgridvariables(cell, var)The position variables (x_i(t) or x_e_i(t) of the same cell) of a variable var of cell that is discretized along the cell, e.g. of cell_views(circuit)[1].c_e_3. Used by the plot recipe to plot a profile against the position in the cell.
BatteryComponents.hppc_pulses — Methodhppc_pulses(time, current, voltage; durations = (18, 2, 4, 10), tolerance = 0.1,
threshold = 0.1, rest_tolerance = 1e-4, temperature = 298.15, soc = nothing,
ocv = nothing)Cut the current pulses out of a recorded pulse test — the hybrid pulse power characterization (HPPC) of the PNGV Battery Test Manual [1], or the constant-current pulses of a resistance test — the way ADVISOR's batmodel tool does [2] (process_HPPC.m and the Rint branch of process_data.m). time [s], current [A, positive while the cell discharges, the package's sign convention] and voltage [V] are the recorded samples.
A pulse is a run of samples whose current keeps one sign and stays at or above threshold in magnitude, with a rest sample (below threshold) on either side. It is kept when its length — from the last rest sample before it to its last sample, ADVISOR's definition — is within tolerance (relative) of one of durations [s]; the default is the 18 s pulse of ADVISOR's HPPC processing and the 2, 4 and 10 s pulses it also accepts, and the long discharges that move the cell between states of charge are thereby left out. Each kept pulse becomes an HPPCPulse holding the samples from its leading rest sample to the last rest sample before the next current step.
The rests have to carry no current. The open-circuit voltage, the state of charge and the resistances are all read from the rest samples, as the voltage of a cell through which no current flows. A rest sample of a kept pulse whose current exceeds rest_tolerance times the pulse's current in magnitude is therefore an ArgumentError, however far below threshold it is; a rest current that is an offset of the measurement has to be zeroed before the record is cut.
temperature [K, or a Unitful temperature] is the temperature of the test, recorded on every pulse and used to group pulses into the temperature axis of rint_tables and rc_tables; pass the test's set point rather than a per-sample measurement, since pulses are grouped by equal temperatures.
The state of charge of each pulse is taken from soc, a vector of the state of charge at every sample (a coulomb count), or found by inverting ocv, an (SOC, T) -> V open-circuit voltage curve increasing in the state of charge (such as a LookupTable), at the rest voltages before and after the pulse. ADVISOR does the latter. A rest voltage outside the curve is taken as full or empty, as ADVISOR does. Pass at most one of them; with neither, the states of charge are NaN. The rest after a pulse has to be long enough for the voltage to relax if ocv is used: a rest voltage still relaxing reads as a state of charge further from the pulse's direction than the cell is.
[1] PNGV Battery Test Manual, Revision 3. DOE/ID-10597, Idaho National Engineering and Environmental Laboratory, February 2001.
[2] ADVISOR 2003-00-r0116, extras/batmodel, Alliance for Sustainable Energy, LLC. https://sourceforge.net/projects/adv-vehicle-sim/
BatteryComponents.linear_ocv — Methodlinear_ocv(; OCV_max, OCV_min, SOC_max = 1, SOC_min = 0, clamped = true)The "open-circuit voltage" entry of an EquivalentCircuitParameters set that rises linearly from OCV_min at SOC_min to OCV_max at SOC_max — the cell treated as a capacitor, and the default open-circuit voltage of Modelica.Electrical.Batteries, whose useLinearSOCDependency = true builds the table OCV_SOC[:,2] = [SOCmin, OCVmin/OCVmax; SOCmax, 1] from exactly these four numbers.
Outside SOC_min .. SOC_max the value is held at the nearer endpoint, matching the HoldLastPoint extrapolation Modelica's table lookup uses. clamped = false extends the line instead, which is what a two-point identification such as He2011LiMn2O4 does, since holding a value the fit never saw is no more meaningful than extending it. Holding leaves a kink at each endpoint, as Modelica's LinearSegments table does, so a run that spends time at the edge of the window is better bounded away from it by the parameter set's "state of charge minimum" and "maximum".
Values may carry Unitful units. The result is a (SOC, T) callable and so is inlined as an expression in the cell's state of charge rather than becoming an overridable parameter; it ignores temperature, as Modelica's one-dimensional table does.
circuit = Dict{String, Any}(
"open-circuit voltage" => linear_ocv(; OCV_max = 4.2u"V", OCV_min = 2.5u"V"),
"series resistance" => 3.0u"mΩ")BatteryComponents.linear_resistance — Methodlinear_resistance(R_ref; alpha = 0, T_ref = 293.15)The entry of an EquivalentCircuitParameters "circuit" section for a resistance that depends linearly on the cell temperature, R = R_ref * (1 + alpha * (T - T_ref)) — the law Modelica.Electrical.Batteries applies to its inner resistance and to the resistors of its RC elements, parameterized there by Ri/R, alpha and T_ref.
alpha is in 1/K and T_ref in K; both may carry Unitful units. Use it for any resistance entry, so each RC branch can carry its own coefficient the way Modelica's rcData records do:
circuit = Dict{String, Any}("open-circuit voltage" => linear_ocv(; OCV_max = 4.2u"V", OCV_min = 2.5u"V"),
"series resistance" => linear_resistance(3.0u"mΩ"; alpha = 0.004u"K^-1"),
"polarization resistance" => [linear_resistance(1.0u"mΩ"; alpha = 0.006u"K^-1")],
"polarization capacitance" => [1000.0u"F"])The temperature it reads is the cell temperature, so it is constant unless the cell is built with temperature = true; with an isothermal cell it evaluates at "initial temperature" and is simply a constant resistance.
BatteryComponents.power — Methodpower(input; time, bounds)Setup for a power experiment. By convention, positive power is discharging and negative power is charging.
Arguments:
input: Power input with units ofW.time: Optional argument to set a maximum experiment time.bounds: Optional experiment-specific stop conditions, e.g.bounds = (V_max = 4.2,)orbounds = :V_max => 4.2, overriding the defaults of theCycler(seedefault_bounds);bounds = falsedisables all stop conditions for this experiment.
BatteryComponents.randles_impedance — Methodrandles_impedance(model::Randles, chemistry, ω; SOC, T)The exact impedance Z(jω) in Ω of the Randles circuit of model with the elements of chemistry at the angular frequency ω [rad/s], evaluated at the state of charge SOC and temperature T [K] (the parameter set's initial values by default). It is Vandeputte et al.'s eq. (11) with the selected diffusion and double-layer elements, R_d tanh(√(jωτ_d))/√(jωτ_d), R_d coth(√(jωτ_d))/√(jωτ_d), 1/(Q_d (jω)^α_d), jω C_dl or Q_dl (jω)^α_dl, and not the finite realization that Randles simulates; the difference between the two is the realization error the model documents. ω may be a vector. At ω = 0 it is the DC limit: R_s + R_ct + R_d for a transmissive Warburg, and infinite for a reflective Warburg or a CPE, which block direct current.
BatteryComponents.rc_initial_guess — Methodrc_initial_guess(pulse::HPPCPulse)The analytic starting point of calibrate_rc: the four quantities of the RCModel's terminal impedance that a pulse determines (see calibrate_rc), read off the pulse as a NamedTuple (; R_0, A, τ, C) [Ω, Ω, s, F].
R_0, the instantaneous resistance, is the voltage step from the rest sample to the first sample of the pulse over the current step there.- The voltage behind
R_0at a sample is its voltage plus its current timesR_0. C, the total capacitance, is the charge the record drew over the change of that voltage from before the pulse to the end of the rest after it.- The polarization left when the pulse ends is that voltage at the end of the rest less that at the end of the pulse;
τis the time after the pulse at which what remains of it has fallen to1/e, andAthe resistance whose polarization, built up with that time constant over the pulse by the current step at its end, is that large.
These are the features of the pulse ADVISOR's process_HPPC.m [1] reads, but ADVISOR turns them into the five elements directly: it splits the step resistance into R_e, R_t and R_c with fixed ratios (1/1.244, 1/1.368 and 1/3.732 of it), takes C_c from a time constant and C_b from the rated energy between the empty and full open-circuit voltages. Those fixed ratios choose the one degree of freedom a pulse leaves open, and the energy-based C_b is not what the pulse measures: on the 18 s, 200 A pulse of SaftHighPower12Ah, with a 3.0-4.1 V window, ADVISOR's start has twice the circuit's total capacitance and a five-hundredth of its polarization resistance A. Where the record shows no polarization to read — a rest too short to relax in, or a first sample that already carries all of the voltage drop at the resolution of the record — the guess falls back to the pulse's length for τ and a tenth of R_0 for A, and a capacitance the rest voltage does not resolve to one whose drift is 1% of the pulse's voltage drop. Six of the 35 pulses of ADVISOR's Evercel records take the fallback.
[1] ADVISOR 2003-00-r0116, extras/batmodel, Alliance for Sustainable Energy, LLC. https://sourceforge.net/projects/adv-vehicle-sim/
BatteryComponents.rc_tables — Methodrc_tables(fits; soc)The "terminal resistance", "end resistance", "capacitor resistance", "bulk capacitance" and "surface capacitance" entries of an EquivalentCircuitParameters circuit for the RCModel, as LookupTables over the state-of-charge breakpoints soc and the temperatures of fits (RCFits from calibrate_rc), each fit placed at the state of charge its pulse started from. The tables are fitted to the pulses as rint_tables's are. Merge them into a circuit with an "open-circuit voltage", which sets the capacitor voltages at the start.
ADVISOR's tables keep the two capacitances constant over the state of charge, averaging the fits at each temperature; here they vary as calibrated, since the resistances were calibrated together with the capacitances of their own pulse and an average would no longer reproduce it. A single capacitance_ratio in calibrate_rc makes the two capacitances vary in proportion.
BatteryComponents.rest — Methodrest(; time, bounds)Setup for a rest experiment. This is a special case of a current experiment where the current is zero.
Arguments:
time: Required argument to set a maximum experiment time.bounds: Optional experiment-specific stop conditions, e.g.bounds = (V_max = 4.2,)orbounds = :V_max => 4.2, overriding the defaults of theCycler(seedefault_bounds);bounds = falsedisables all stop conditions for this experiment.
BatteryComponents.rint_resistance — Methodrint_resistance(pulse::HPPCPulse)The resistance of the Rint model that reproduces pulse: the voltage the cell recovers once the pulse ends, from its last voltage under load to the voltage at the end of the following rest, over the step in the current between those two samples,
R = (voltage[end] - voltage[pulse_end]) / (current[pulse_end] - current[end])This is the resistance of ADVISOR's Rint processing [1] (process_data.m), which counts everything between the equilibrium and the loaded voltage as internal resistance rather than separating an instantaneous drop from a polarization. Under load the Rint model's voltage is OCV(SOC) - I R, and at a rest, which hppc_pulses requires to carry no current, it is OCV(SOC). The resistance is exactly the model's when the current steps between two samples, held at the pulse current up to the last loaded sample and zero from the next, as a cycler switches it: no charge moves between the two samples, so the state of charge is the same at both, soc_after, which is where rint_tables places the resistance. When the current instead falls over an interval Δt (a ramp resolved by the samples, the waveform the RC calibration replays between them), the charge ΔI Δt / 2 it carries moves the state of charge between the two samples. The resistance found then differs from the model's at the state of charge of the loaded sample by
δR = -Δt (dOCV/dSOC) / (7200 Q)for a capacity Q [A⋅h], whatever the current and its direction, exactly so where the open-circuit voltage is linear over the charge moved: -0.14% of 0.1 Ω for a 1 s ramp of a 1 A⋅h cell whose open-circuit voltage rises by 1 V over the state of charge. Placed at soc_after, as rint_tables places it, a resistance that varies with the state of charge adds R(SOC_loaded) - R(soc_after) = ΔI Δt (dR/dSOC) / (7200 Q) to that error; for R = 0.1 + SOC Ω in the example the two cancel. ADVISOR's resistance has the same bias.
ADVISOR divides by the time-average of the current over the pulse rounded to whole amperes; this uses the current step itself, which for a constant-current pulse of 7.3 A is 4% apart from ADVISOR's 7 A. The test suite reproduces ADVISOR's resistances of its own sample data up to exactly that factor.
[1] ADVISOR 2003-00-r0116, extras/batmodel, Alliance for Sustainable Energy, LLC. https://sourceforge.net/projects/adv-vehicle-sim/
BatteryComponents.rint_tables — Methodrint_tables(pulses; soc)The "discharge resistance" and "charge resistance" entries of an EquivalentCircuitParameters circuit for the Rint model, as LookupTables over the state-of-charge breakpoints soc and the temperatures the pulses were recorded at: the rint_resistance of each of pulses at its soc_after, discharging pulses in the first table and charging ones in the second. For a current that ramps down between samples rather than stepping, a table value is off by rint_resistance's bias at the loaded state of charge plus the change of the resistance from there to soc_after, which rint_resistance states. The result merges into a circuit section that also has an "open-circuit voltage":
pulses = hppc_pulses(time, current, voltage; temperature = 25u"°C", ocv)
circuit = merge(Dict{String, Any}("open-circuit voltage" => ocv),
rint_tables(pulses; soc = 0.1:0.1:0.9))At each temperature a table's values are the least-squares fit of the table's own piecewise-linear interpolant to the pulses, so a table whose breakpoints are the pulses' states of charge passes through every pulse, and several pulses at one breakpoint — pulses at several currents, which the Rint model cannot tell apart — are averaged. A breakpoint no pulse lies next to takes the value interpolated between its neighbours, or held from the nearest one beyond the pulses, as a LookupTable holds its edges. Breakpoints closer together than the pulses are rejected, and so is a table with a value that is not positive, which breakpoints beyond the pulses' states of charge can extrapolate the pulses' trend to; place the breakpoints within the range the pulses cover. ADVISOR instead fits a cubic in the open-circuit voltage through all the pulses, whose extrapolation it warns can turn negative.
BatteryComponents.table_lookup — Methodtable_lookup(table, x)
table_lookup(table, x, y)The value of the LookupTable table at x, or at (x, y) for a two-dimensional table: the pure, registered function through which a model reads a table.
In an equation, table is a nonnumeric parameter holding the table, so that the table is part of the problem's parameters and not of its generated code; a table object evaluated at symbolic coordinates throws an ArgumentError instead. Derivatives with respect to the coordinates are registered, the slope of the interpolant inside the grid and zero where it is held, so a Jacobian built by mtkcompile with jac = true is exact. Broadcasting it, table_lookup.(table, x, y) over array variables, evaluates one shared table at every element as a single array equation.
BatteryComponents.voltage — Methodvoltage(input; time, bounds)Setup for a voltage experiment.
Arguments:
input: Voltage input with units ofV.time: Optional argument to set a maximum experiment time.bounds: Optional experiment-specific stop conditions, e.g.bounds = (V_max = 4.2,)orbounds = :V_max => 4.2, overriding the defaults of theCycler(seedefault_bounds);bounds = falsedisables all stop conditions for this experiment.