Fit on C/5 and C/2. Predict 2C blind.

A Doyle-Fuller-Newman half-cell model of a commercial LiMn₂O₄ cathode in PyBaMM, parameterised with the open-circuit curve from my own C/10 data. Three fitted parameters, then validation on the 2C cycle and the cyclic voltammograms the fit never saw. Every number regenerates from the raw cycler files.

Scroll
0mV
training RMSE on C/5 and C/2 with three fitted parameters
0mV
blind 2C average discharge voltage error
0mV
largest error over six CV peak potentials at three scan rates, never fitted
0
automated tests on the parser, OCV, model and every fit version
01 · The measurement

One coin cell, seven tests, four C-rates, three scan rates.

Commercial LiMn₂O₄ sheet against lithium metal on a Bio-Logic VMP-300. Galvanostatic cycling at C/10, C/5, C/2 and 2C between 3.5 and 4.5 V with a 30 s rest after every step, and cyclic voltammetry at 0.1, 0.2 and 0.3 mV/s. At 2C the cell keeps 58 % of its C/10 capacity and 53 % of its energy; round-trip energy efficiency falls from 95 % at C/5 to 82 % at 2C.

The cell as measured, explodedLi metal, Al foilLiMn₂O₄ coating
10 mm disc, 85 µm coating of 5 µm particles on 15 µm aluminium, against lithium metal; the thicknesses in the scene are the ones in docs/assets/data.js. Drag to orbit.
RateI (mA)Q (mAh)V̄ (V)E (mWh)RTE (%)

Representative cycle per rate (cycle 1; cycle 2 at 2C because cycle 1 followed a CV that ended at 3.0 V). RTE is discharge energy over charge energy of the same cycle; C/10 is lowered by first-cycle parasitic oxidation near 4.5 V (coulombic efficiency 91 %).

Measurement artefacts, flagged and handled
  • C/10 current range: run on the 10 mA range, so the current reads 0.147 / 0.140 mA against 0.143 set. The measured current is integrated, not the set point.
  • C/5 contact disturbance: a 22 mV step on the second discharge, current unchanged. Cycle 1 is used for fitting; the step returns at the switch-off, which confirms it as a contact resistance.
  • 2C history: the first 2C charge removed extra lithium after a CV ending at 3.0 V. Cycle 2 is the representative 2C cycle and the model is run through cycle 1 to carry the right history.
  • CV auto-ranging: current-range switches near ±1 mA and a -8.8 mA inrush at the start of the 0.2 mV/s file are excluded from the peak search.
02 · Validation on data the fit never saw

Three parameters, fitted on two rates, reproduce the other two and a different technique.

Solid-diffusion time constant, reaction rate constant and contact resistance were fitted by nonlinear least squares on the C/5 and C/2 curves only (26 mV RMSE). C/10 is a low-rate check, 2C is a blind prediction, and the CVs are simulated by feeding the model the measured voltage programme.

Measured against DFN at four ratesC/10C/5C/22C
Ribbons: measured. Lines: DFN. C/5 and C/2 were used for the fit, C/10 is a low-rate check, 2C is the blind prediction. Hover a ribbon for the point and the capacity comparison.
RateRoleQ meas / model (mAh)ΔV̄ (mV)V-Q RMSE (mV)

The 2C average voltage lands within 17 mV; the capacity is over-predicted by 20 % because the C/5 and C/2 curves fix the sum of the ohmic and the transport losses, and the 30 s rests then separate the two, which the later model versions build on.

Scan rateOx. peak meas / DFN (V)Red. peak meas / DFN (V)Largest shift (mV)

b-values (slope of log peak current against log scan rate): measured , model . Both sit between the diffusion (0.5) and surface (1.0) limits, as expected for a porous electrode.

Cyclic voltammetry, never fitted0.10.20.3 mV/s
The model is driven by the measured voltage programme; all six peak potentials sit within 80 mV of the measurement. Hover for the peak comparison.
03 · Where the 2C voltage goes

The model names the loss. The rests measure its ohmic part independently.

PyBaMM's voltage-component variables close to the terminal voltage to better than a microvolt, so the 374 mV capacity-weighted mean loss on the 2C discharge can be split by mechanism. Then the 30 s rests after every step, read straight from the raw files, give a model-free check on the ohmic part.

Capacity-weighted mean voltage loss at 2C: 374 mV

DFN v1, 10 mm disc
contact / ohmic 0 %
charge transfer 0 %
particle diffusion 0 %
electrolyte 0 %

74 % ohmic and contact resistance

A lumped resistance of 97 Ω carries most of the loss: current-collector contact, separator and the lithium-metal interphase, all in one number.

17 % charge transfer

Butler-Volmer kinetics with the fitted rate constant. The log-parameters k and R_contact are correlated at 0.94, so the data split these two losses only weakly.

6 % solid-state diffusion, 3 % electrolyte

Diffusion in 5 µm particles with the fitted time constant R²/D of about 2,200 s. At the 3.5 V cut-off the particles' bulk open-circuit voltage is still 3.95 V: 0.15 mAh of lithium the model could not deliver at that rate.

The rests measure it: 72 Ω against the fitted 97 Ω

The voltage jump 48 ms after every current interruption gives the instantaneous resistance model-free. After charge it is 72 Ω at every rate from C/10 to 2C, which pins the ohmic part of the loss independently of the fit; the relaxation that follows is linear in log(time), the signature of the double-layer physics the next version adds.

Give the model a double layer: rest misfit 40 → 15 mV

Adding double-layer capacitance (one PyBaMM option, one extra parameter) lets the same training data fit the rests to 15 mV instead of 40 mV, with the contact resistance at 89 Ω, in line with the rests. Every version is tested and reported in the repository, down to a side-reaction submodel that reproduces the first-cycle coulombic efficiency.

04 · Reproduce it

From raw cycler files to every figure, table and number.

The raw EC-Lab exports are in the repository and are never modified. One command regenerates the processed data, the fits, the validation, the figures and the README text; no number in the README is typed by hand.

git clone https://github.com/Soham-ChemE/LMO-Cathode-Rate-Model-PyBaMM.git
cd LMO-Cathode-Rate-Model-PyBaMM
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt && pip install -e .
make test                        # 58 tests, under 10 s
python scripts/run_all.py --fast # SPMe only, a few minutes; omit --fast for the DFN headline
python docs/build_assets.py      # this page's data and figures
Cite

S. Kavathekar, LiMn₂O₄ half cell: a physics-based PyBaMM rate model fitted to measured galvanostatic data, MSE 5550 project, University of Pennsylvania, 2026. github.com/Soham-ChemE/LMO-Cathode-Rate-Model-PyBaMM

Scope and assumptions

One cell measured in sequence, one cycle per rate; the electrode area is derived from capacity with the disc size that gives a physically consistent coating; nothing was tuned on the 2C or CV data.