Skip to content

Releases: tum-ees/PyDMA

v1.1.0 — Python 3.12 floor, PyBaMM-safe Si OCP, seeded golden tests

Choose a tag to compare

@mathiasrehm mathiasrehm released this 26 May 08:28

v1.1.0 — Python 3.12 floor, PyBaMM-safe Si OCP, seeded golden tests

Major release. Drops Python 3.9-3.11, modernizes typing, adds a PyBaMM-stable silicon OCP filter, and locks scientific behavior with a seeded regression suite.

Highlights

  • PyBaMM-safe silicon OCP filter. New pydma.silicon.strict_sto.pchip_resample_for_pybamm produces a smooth strictly-monotone Si OCP on a uniform sto grid with an optional endpoint-V snap. More stable for PyBaMM's CasADi/IDAS interpolant. Replaces the previous strict_sto_eps_spread helper.
  • LOWESS-on-PCHIP gotcha documented. When re-fitting a PCHIP-output curve through PyDMA itself, set DMAConfig(smoothing_points=1) — the default 30 over-smooths the already-smoothed input and the optimizer basin-escapes (measured on Molicel M35A in discharge direction: RMSE 3.3 → 21 mV, γ_Si 0.293 → 0.18; M35A dataset not included).
  • Python ≥ 3.12 required. Drops 3.9–3.11 and the from __future__ import annotations shims. Runtime floors bumped to the lowest 3.12-wheel releases: numpy>=1.26, scipy>=1.11.4, pandas>=2.1.1, matplotlib>=3.8, statsmodels>=0.14.
  • Deterministic optimizer + scientific regression suite. DMAConfig.random_seed is now a real settable field (default None preserves prior nondeterministic behavior). New opt-in pytest -m scientific suite locks down a seeded P45B/NCA fit against golden RMSE / parameter / degradation-mode numbers, and skips cleanly from an unpacked sdist when its data files aren't present.
  • Maintainer ops. Added RELEASING.md checklist; both tutorial notebooks (getting_started.ipynb, pybamm_integration.ipynb) are now release artifacts. Internal: typing modernized to PEP 585/604/695 and mypy src/pydma is clean.

Install

pip install --upgrade pydma==1.1.0

PyPI: https://pypi.org/project/pydma/1.1.0/ · Full notes: CHANGELOG.md

v1.0.2 — PyDMA → PyBaMM balancing bridge

Choose a tag to compare

@mathiasrehm mathiasrehm released this 12 May 14:27

A PyDMA fit now plugs directly into a PyBaMM ParameterValues.

Highlights

  • PyDMA → PyBaMM bridge. The new pydma.utils.balancing module derives c_max and c_init(SoC) directly from a voltage-anchored PyDMA fit plus the user-supplied cell geometry. ElectrodeBalancing.pybamm_overrides(soc) returns a dict keyed by PyBaMM's exact parameter names, ready for pybamm.ParameterValues.update(...).
  • New notebook notebooks/pybamm_integration.ipynb: end-to-end bridge for the Molicel INR21700-P45B, verified by a C/500 DFN charge round-trip. All material/geometry values come from Frank et al. (2025), Table III (DOI 10.1149/1945-7111/adc03c). Chen2020 is used only as a public Li-ion fallback base for parameters Frank et al. do not document.
  • New data file notebooks/parameter_data/frank2025_p45b_table_iii.json: 24 Frank et al. Table III constants as {value, unit, source}.
  • notebooks/getting_started.ipynb is now purely a DMA-analysis tutorial.

Install

pip install --upgrade pydma==1.0.2

PyPI: https://pypi.org/project/pydma/1.0.2/ · Full notes: CHANGELOG.md

v1.0.1 — corrected voltage-anchored stoichiometry export

Choose a tag to compare

@mathiasrehm mathiasrehm released this 29 Apr 11:11

Highlights

  • Stoichiometry windows now match the requested voltage cutoffs. Anode and cathode stoichiometry windows are anchored to the fitted reconstructed cell voltage at the requested voltage limits, via DMAResult.voltage_anchored_windows(...). The previous output used raw internal fit-window endpoints, which in most cases did not correspond to the measured pseudo-OCV voltage cutoffs — exported values were systematically off for downstream consumers. For inhomogeneous fits, the anchored values are the central/nominal stoichiometries of the fitted trajectory.
  • Composite anode phase mapping. BlendElectrode.get_component_stoichiometries(...) and BlendElectrode.get_component_stoichiometry_window(...) map a fitted blend coordinate to per-phase graphite/silicon stoichiometries, so anchored blend coordinates are also exported as Gr/Si stoichiometry windows.
  • Per-phase inspection helper. FittedParams.sto_window_an_per_phase(...) exposes raw per-phase windows when needed.
  • Strictly monotone silicon OCP. generate_si_curve(monotone_filter=True) now returns strictly monotone output, making the filtered curve safe for downstream spline interpolation (e.g. PyBaMM preprocessing) without changing fitting results.
  • Updated getting_started.ipynb to demonstrate fitted-reconstruction voltage anchoring and anchored Gr/Si phase windows.

See the full CHANGELOG.md for details.

v1.0.0

Choose a tag to compare

@mathiasrehm mathiasrehm released this 13 Apr 10:42

Highlights

  • New: inhomogeneity offset (inhom_anode_offset, inhom_cathode_offset) — MATLAB inhomOffsetFraction parity.
  • Numerical: q0 restored to MATLAB parity (span of the normalized SOC axis). Fits with weight_dva > 0 and/or weight_ica > 0 may differ slightly from PyDMA ≤ 0.1.0. OCV-only fits are unaffected.

Install: pip install pydma==1.0.0


Added

  • Inhomogeneity offset for anode and cathode (DMAConfig.inhom_anode_offset,
    DMAConfig.inhom_cathode_offset, default 0.0, validated [0, 1]). A
    positive offset allows a fraction of the maximum inhomogeneity spread to
    be present already at SOC = 0 instead of starting from zero. Setting the
    offset to 1.0 reproduces SOC-independent inhomogeneity, which is
    analogous to earlier degradation mode analysis frameworks in literature.
    Matches MATLAB's new inhomOffsetFraction argument
    (calculate_inhomogeneity.m).
  • DMAAnalyzer.analyze_aging_study(path, ...) convenience API that accepts
    a directory or single .mat file, loads it using the configured
    direction, and runs every CU.
  • Top-level load_aging_study export and support for single-file multi-CU
    .mat payloads in the loader.
  • Isotonic-regression-based silicon OCP filtering in generate_si_curve,
    producing strictly monotonic curves while keeping the maximum amount of
    information.
  • Regression tests pinning MATLAB-parity invariants (q0, fitted-bounds,
    degradation-mode delegation, inhomogeneity offset formula, loader CU
    handling, reset-state completeness, FittedParams None handling).

Changed

  • Numerical: q0 now matches MATLAB (span of the normalized SOC axis,
    ≈ 1.0) instead of the raw Ah span. Because the DVA and ICA cost
    contributions scale as q0², this may produce small numerical
    differences compared with older PyDMA versions when weight_dva and/or
    weight_ica are non-zero
    . In return, fits are now cell-size independent
    and consistent with the MATLAB-tuned weight_dva / weight_ica defaults.
    OCV-only fits (weight_dva = 0, weight_ica = 0) are unaffected.
  • Breaking: compare_with_reference now delegates to
    calculate_degradation_modes, so blend LAMs
    (lam_anode_blend1/2, lam_cathode_blend1/2) are populated rather
    than silently zero. Constructor keyword arguments for DegradationModes
    renamed lam_an / lam_calam_anode / lam_cathode (the short
    names remain available as read-only property aliases).
  • DMAConfig.algorithm is now actually consumed by the optimizer, and
    DMAConfig.get_initial_guess() now includes blend-weight initial values.
  • Aging-study runs now populate real fit_ocv_mse / fit_dva_mse /
    fit_ica_mse and the is_accepted / status / algorithm metadata
    on every DMAResult instead of placeholder values.
  • Aging-study loader honors the configured direction when choosing
    per-CU folders.

Fixed

  • Inhomogeneity out-of-range clamping now uses
    np.interp(..., left=voltage[0], right=voltage[-1]), matching MATLAB
    griddedInterpolant(..., 'linear', 'nearest'). The previous code
    clamped both OOB sides to voltage[-1], a latent mismatch that affected
    fits even when inhom_offset = 0.
  • compare_with_reference now falls back to
    self.reference_data.reference_capacity, and its capacity-loss guard
    protects against division by zero (reference_capacity == 0).
  • FittedParams type annotations and to_array() correctly handle None
    for disabled blend/inhomogeneity parameters and always return a
    float64 numpy array.
  • DMAAnalyzer.reset_state now also clears _capacity_history and the
    normalized-SOC warning flag, so repeated aging studies start clean.
  • Loader now handles nested .mat structs (mat_struct) and single-file
    multi-CU .mat payloads, and falls back to direction-based folder
    matching when no explicit CU markers are present.
  • Reoriented-OCV warning is now one-shot and only fires when
    auto-correction implies a direction opposite to config.direction.
  • DMAConfig now validates blend initial guesses against their upper
    bounds and rejects out-of-range inhomogeneity offsets at construction
    time.

Removed

  • Dead DMAConfig fields and the unused internal direction threading
    in the loader's CU matcher.