PyDMA is a Python package for performing degradation mode analysis of lithium-ion and sodium-ion batteries. Among others, both electrodes can be modeled as blends, and inhomogeneity is available for both electrodes. It reconstructs measured pseudo-OCV curves using half-cell electrode potential curves to quantify three degradation mechanisms:
- LLI: Loss of lithium inventory (charge carrier loss)
- LAM_an: Loss of active material at anode
- LAM_ca: Loss of active material at cathode
The core algorithm reconstructs full-cell OCV as:
OCV_cell(SOC) = U_cathode(α_ca · SOC + β_ca) - U_anode(α_an · SOC + β_an)
Where α scales capacity and β shifts the SOC window.
Install from PyPI:
pip install pydmaOr install from source:
git clone https://github.com/tum-ees/pydma.git
cd pydma
pip install .For development installation:
git clone https://github.com/tum-ees/pydma.git
cd pydma
pip install -e ".[dev,notebook]"import pydma
from pydma import DMAAnalyzer, DMAConfig
# Load your electrode OCP data
anode = pydma.load_ocp("path/to/anode_ocp.csv", electrode_type="anode")
cathode = pydma.load_ocp("path/to/cathode_ocp.csv", electrode_type="cathode")
# Create analyzer with configuration
config = DMAConfig(
direction="charge",
weight_ocv=100,
weight_dva=1,
weight_ica=0,
)
analyzer = DMAAnalyzer(
config=config,
anode=anode,
cathode=cathode,
)
# Run analysis on aging study data
# The analyzer uses config.direction when loading the study.
results = analyzer.analyze_aging_study("path/to/aging_data")
# Access degradation modes
print(f"LLI: {results['CU2'].degradation_modes.lli:.2%}")
print(f"LAM_an: {results['CU2'].degradation_modes.lam_anode:.2%}")
print(f"LAM_ca: {results['CU2'].degradation_modes.lam_cathode:.2%}")
# Plot results
results.plot_degradation_modes()Supports blended electrodes (e.g., Silicon-Graphite anodes):
from pydma import BlendElectrode
config = DMAConfig(
use_anode_blend=True,
gamma_anode_blend2_upper=0.30, # Max 30% silicon
)
si_gr_anode = BlendElectrode(blend1=graphite_ocp, blend2=silicon_ocp)
analyzer = DMAAnalyzer(
config=config,
anode=si_gr_anode,
cathode=cathode,
)Models electrode inhomogeneity effects:
config = DMAConfig(
allow_anode_inhomogeneity=True,
allow_cathode_inhomogeneity=True,
max_inhomogeneity=0.3,
inhom_anode_offset=0.2,
inhom_cathode_offset=0.0,
)Combine OCV, DVA, and ICA fitting with custom weights:
config = DMAConfig(
weight_ocv=100,
weight_dva=1,
weight_ica=0,
roi_dva_min=0.1,
roi_dva_max=0.9,
)Choose optimization thoroughness:
config = DMAConfig(speed_preset="thorough") # "fast", "medium", or "thorough"Generate silicon OCP from measured blend electrode data:
from pydma.silicon import generate_si_curve
result = generate_si_curve(
blend_path="path/to/blend_ocp.mat",
graphite_path="path/to/graphite_ocp.mat",
gamma_si=0.245,
)The optimizer uses an 8-element parameter vector internally:
| Index | Parameter | Description |
|---|---|---|
| 0 | α_an | Anode scaling / capacity ratio |
| 1 | β_an | Anode offset / SOC shift |
| 2 | α_ca | Cathode scaling |
| 3 | β_ca | Cathode offset |
| 4 | γ_blend2_an | Anode blend2 fraction (0 if disabled) |
| 5 | γ_blend2_ca | Cathode blend2 fraction (0 if disabled) |
| 6 | σ_an | Anode inhomogeneity magnitude |
| 7 | σ_ca | Cathode inhomogeneity magnitude |
See the Getting Started Notebook for detailed examples.
See CHANGELOG.md for the full release history.
1.0.0 highlights:
- New: inhomogeneity offset (
inhom_anode_offset,inhom_cathode_offset) lets a fraction of the maximum inhomogeneity spread be present already at SOC = 0, matching MATLAB's newinhomOffsetFractionargument. - Numerical change:
q0is now the span of the normalized SOC axis (≈ 1.0), matching MATLAB. Previously, PyDMA multiplied DVA/ICA costs by the raw Ah capacity, so fits withweight_dva > 0and/orweight_ica > 0may produce small numerical differences compared with PyDMA ≤ 0.1.0. Fits are now cell-size independent and consistent with the MATLAB-tuned weight defaults. OCV-only fits are unaffected.
This is a Python translation of the TUM-EES DegradationModeAnalysis MATLAB framework. We would like to thank Johannes Natterer for providing the aging data set of a cyclic aged P45B cell and for help in translating into Python.
- Mathias Rehm, Chair of Electrical Energy Storage Technology, School of Engineering and Design, Technical University of Munich, 80333 Munich, Germany
- Josef Eizenhammer, Chair of Electrical Energy Storage Technology, School of Engineering and Design, Technical University of Munich, 80333 Munich, Germany
- Moritz Günthner (student research project)
- Can Korkmaz (student research project)
This framework is the Python implementation of the MATLAB DegradationModeAnalysis toolbox. If you use this repository in any publication, please cite:
M. Rehm et al., "How to determine the degradation modes of lithium-ion batteries with silicon–graphite blend electrodes," Journal of Power Sources, 2026, DOI: 10.1016/j.jpowsour.2026.239418
The framework is also applied and validated on commercial sodium-ion batteries in the following publication. We appreciate citing this work as well, and kindly ask you to do so if your work involves sodium-ion cells:
M. Rehm et al., "Aging of commercial sodium-ion batteries with layered oxides: how to measure and analyze it?," EES Batteries, 2026, DOI: 10.1039/D5EB00221D
BSD 3-Clause "New" or "Revised" License - see LICENSE for details.
