Battery Pack 24-Cell Module
PARITYS3 · dim 254No clear winner. The survival gap is under 10 percentage points and the balanced-score gap is under 0.05, so neither SolvSRK nor the best baseline clears the win threshold. Either works - choose on cost, licensing, or integration effort. All verdicts →
24-cell 6x4 module with 4-stage TR and 2D thermal coupling (dim=254, S3)
Problem definition
Hatchard & Dahn (2001); SAE J2464
Canonical RHS excerpt from the registered callable used for this benchmark cell. Expand it to verify the state equations; it is not a standalone runnable fixture.
Show canonical RHS excerpt
def _bp24_cell_idx(r, c):
return r * _BP24_NC + c
def _four_stage_decomposition(alpha_sei, alpha_ae, alpha_ca, alpha_el, T):
k_sei = _arrhenius_rate(_A_SEI, _E_SEI, T)
k_ae = _arrhenius_rate(_A_AE, _E_AE, T)
k_ca = _arrhenius_rate(_A_CA, _E_CA, T)
k_el = _arrhenius_rate(_A_EL, _E_EL, T)
d_sei = -k_sei * alpha_sei
d_ae = k_ae * alpha_ae * (1.0 - alpha_ae)
if alpha_ae < 1e-12 and alpha_sei < 0.15 - 1e-6:
d_ae = k_ae * 1e-6
d_ca = k_ca * (1.0 - alpha_ca)
d_el = k_el * (1.0 - alpha_el)
q_dot = (_Q_SEI * _W_SEI * abs(d_sei)
+ _Q_AE * _W_AE * d_ae
+ _Q_CA * _W_CA * d_ca
+ _Q_EL * _W_EL * d_el)
return d_sei, d_ae, d_ca, d_el, q_dot
def _single_cell_4stage(state, T_amb_eff):
"""4-stage dynamics for one cell. Returns (dy[8], q_gen)."""
alpha_sei = np.clip(state[0], 0.0, 1.0)
alpha_ae = np.clip(state[1], 0.0, 1.0)
alpha_ca = np.clip(state[2], 0.0, 1.0)
alpha_el = np.clip(state[3], 0.0, 1.0)
T = np.clip(state[4], 250.0, 2000.0)
d_sei, d_ae, d_ca, d_el, q_dot = _four_stage_decomposition(
alpha_sei, alpha_ae, alpha_ca, alpha_el, T)
q_gen = q_dot * _M_CELL
q_cool = _H_CONV * _A_SURF * (T - T_amb_eff)
dT = (q_gen - q_cool) / (_M_CELL * _CP)
dQ = q_gen
n_gas_max = 0.01
n_gas = alpha_el * n_gas_max
dn_gas = n_gas_max * d_el
dP = (dn_gas * _R_GAS * T + n_gas * _R_GAS * dT) / _V_HEAD
dR = _R0 * (0.5 * abs(d_sei) + 2.0 * d_ae)
dy = np.empty(8)
dy[0] = d_sei
dy[1] = d_ae
dy[2] = d_ca
dy[3] = d_el
dy[4] = dT
dy[5] = dQ
dy[6] = dP
dy[7] = dR
return dy, q_gen
def _bp24_rhs(t, y):
cells = [y[i * _CELL_DIM_4STAGE:(i + 1) * _CELL_DIM_4STAGE]
for i in range(_BP24_N_CELLS)]
T = np.array([np.clip(cells[i][4], 250.0, 2000.0)
for i in range(_BP24_N_CELLS)])
flux_offset = _BP24_CELL_BLOCK
loss_offset = flux_offset + _BP24_N_EDGES
q_edge = y[flux_offset:loss_offset]
q_loss = y[loss_offset:]
dy = np.zeros(_BP24_DIM)
cell_dy = []
for i in range(_BP24_N_CELLS):
cdy, _ = _single_cell_4stage(cells[i], _T_AMB)
cell_dy.append(cdy)
# Horizontal edges
edge_idx = 0
for r in range(_BP24_NR):
for c in range(_BP24_NC - 1):
ci = _bp24_cell_idx(r, c)
cj = _bp24_cell_idx(r, c + 1)
q_cond = _K_CONTACT * _A_CONTACT * (T[ci] - T[cj]) / _D_GAP
q_rad = _SIGMA * _EMISSIVITY * _A_CONTACT * (T[ci]**4 - T[cj]**4)
q_total = q_cond + q_rad
cell_dy[ci][4] -= q_total / (_M_CELL * _CP)
cell_dy[cj][4] += q_total / (_M_CELL * _CP)
dy[flux_offset + edge_idx] = (q_total - q_edge[edge_idx]) / 0.1
edge_idx += 1
# Vertical edges
for r in range(_BP24_NR - 1):
for c in range(_BP24_NC):
ci = _bp24_cell_idx(r, c)
cj = _bp24_cell_idx(r + 1, c)
q_cond = _K_CONTACT * _A_CONTACT * (T[ci] - T[cj]) / _D_GAP
q_rad = _SIGMA * _EMISSIVITY * _A_CONTACT * (T[ci]**4 - T[cj]**4)
q_total = q_cond + q_rad
cell_dy[ci][4] -= q_total / (_M_CELL * _CP)
cell_dy[cj][4] += q_total / (_M_CELL * _CP)
dy[flux_offset + edge_idx] = (q_total - q_edge[edge_idx]) / 0.1
edge_idx += 1
# Pack cell derivatives and loss trackers
for i in range(_BP24_N_CELLS):
dy[i * _CELL_DIM_4STAGE:(i + 1) * _CELL_DIM_4STAGE] = cell_dy[i]
q_loss_actual = _H_CONV * _A_SURF * (T[i] - _T_AMB)
dy[loss_offset + i] = (q_loss_actual - q_loss[i]) / 1.0
return dy- Parameters
- _A_AE = 2.5e+13
- _A_CA = 6.667e+13
- _A_CONTACT = 0.0004
- _A_EL = 5.14e+25
- _A_SEI = 1.667e+15
- _A_SURF = 0.000818
- _BP24_CELL_BLOCK = 192
- _BP24_DIM = 254
- _BP24_NC = 4
- _BP24_NR = 6
- _BP24_N_CELLS = 24
- _BP24_N_EDGES = 38
- _CELL_DIM_4STAGE = 8
- _CP = 830
- _D_GAP = 0.001
- _EMISSIVITY = 0.8
- _E_AE = 135080
- _E_CA = 139600
- _E_EL = 274000
- _E_SEI = 135080
- _H_CONV = 10
- _K_CONTACT = 0.5
- _M_CELL = 0.044
- _Q_AE = 1.714e+06
- _Q_CA = 314000
- _Q_EL = 155000
- _Q_SEI = 257000
- _R0 = 0.02
- _R_GAS = 8.314
- _SIGMA = 5.67e-08
- _T_AMB = 298
- _V_HEAD = 1e-06
- _W_AE = 0.5
- _W_CA = 0.25
- _W_EL = 0.217
- _W_SEI = 0.033
- Initial condition
- y(0) = [0.15, 0, 0, 0, 450, 0, …] [shape=(254,), min=0, max=101325]
- Horizon
- t ∈ [0, 3600]
Canonical RHS excerpt captured from the same registered callable used for the published benchmark. Frozen closure values are summarized below; helper imports and solver settings are intentionally omitted.
Fingerprint
Spread: extreme
Default noise: high
Recommendation snapshot
Clean best: SolvSRK
Noisy best: SciPy BDF
Coverage
14 solver arms · clean + 5 noise levels
Ranked on survival, precision, and speed
Versions & freeze
Methodology →- Freeze
- 2026-08-13
- libsolvsrk
- 2.3.0
- SciPy
- 1.14
- SUNDIALS
- CVODE (bundled backend)
20 seeds/cell default · 14 arms · TRL 4–5 · simulation-lab validated · this page: Battery Pack 24-Cell Module (battery-pack-24-cell-module)
Governed SolvTune benchmark freeze; per-arm medians only. RHS definitions and raw trial rows are not published.
Self-reported by Resonix Labs · not independently verified
Results matrix
Pick an objective and a noise level to rank all arms on survival, median SCD, median nfev, and median wall time. Medians across seeds.
Objective
Best overall trade-off of survival, precision, and speed.
Noise level
| # | Solver | Survival | SCD | nfev | Wall | Score |
|---|---|---|---|---|---|---|
| 1 | SolvSRK | 100% | 10.7 | 28,442 | 12.58 s | 0.873 |
| 2 | Tsit5external | 100% | 9.9 | 61,836 | 53.72 s | 0.855 |
| 3 | SciPy LSODASciPy | 100% | 9.5 | 13,846 | 10.49 s | 0.846 |
| 4 | SciPy RadauSciPy | 100% | 9.4 | 5,023 | 4.04 s | 0.843 |
| 5 | CVODE Adamsexternal | 100% | 9.1 | 10,579 | 8.10 s | 0.835 |
| 6 | CVODE BDFexternal | 100% | 8.4 | 2,490 | 1.91 s | 0.819 |
| 7 | SciPy BDFSciPy | 100% | 8.2 | 2,107 | 1.69 s | 0.814 |
| - | SciPy RK45SciPy | 0% | - | - | - | - |
| - | SciPy DOP853SciPy | 0% | - | - | - | - |
| - | SciPy RK23SciPy | 0% | - | - | - | - |
At Clean, best balanced arm is SolvSRK.
Values are medians across seeds, measured by Resonix Labs on Resonix hardware and not independently verified; nfev and wall are on reference lab hardware (indicative). Under injected noise only SolvSRK and the SciPy arms are run. How we measure accuracy → · Verification status →
Cite this page
Replace the access date. Pin the freeze ID and library versions when comparing against a later export. Cite it as what it is - a self-reported vendor benchmark, not an independently verified result. The note field says so; please keep it.
@misc{resonix_evidence_battery_pack_24_cell_module_2026,
title = {Resonix Evidence Portal: Battery Pack 24-Cell Module},
author = {{Resonix Labs (Canada) Inc.}},
year = {2026},
howpublished = {\url{https://resonixusa.com/evidence/problems/battery-pack-24-cell-module}},
note = {Self-reported vendor benchmark; internally generated by Resonix Labs and not independently verified. Accessed YYYY-MM-DD. Freeze 2026-08-13; libsolvsrk 2.3.0; SciPy 1.14.}
}Related
TRL 4–5 · simulation-lab validated · 398 problems · 14 solver arms · clean + 5 noise levels
Freeze: 2026-08-13 · scipy 1.14 · libsolvsrk 2.3.0 · Methodology
Self-reported by Resonix Labs · not independently verified · Verification status