Changelog¶
All notable changes to the Soft Potato project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning and PEP 440.
[Unreleased]¶
[3.1.1] - 2026-10-02¶
Patch Release: IUPAC Sign Convention Bug Fix & Cyclic Voltammetry Tutorial¶
Soft Potato 3.1.1 is a patch release resolving a sign convention bug in electrochemical current calculations to strictly enforce IUPAC polarity across analytical, solver, and fitting modules (cathodic reduction currents are negative, \(I < 0\); anodic oxidation currents are positive, \(I > 0\)), introducing an interactive cyclic voltammetry tutorial notebook, and enhancing CI workflow automation.
Fixed¶
- Electrochemical Current IUPAC Sign Convention Bug:
- Resolved sign convention bug across analytical equations, numerical solvers, and parameter fitting routines to strictly enforce the IUPAC convention (cathodic reduction currents are negative, \(I < 0\); anodic oxidation currents are positive, \(I > 0\)).
softpotato.solver.base: Corrected Faradaic current calculation from interfacial diffusive flux (\(J = -D (\partial c/\partial x)|_{x=0}\)) so that cathodic reduction yields negative current (\(I_{\text{cathodic}} = n F A J_{\text{Ox}} < 0\)) and anodic oxidation yields positive current (\(I_{\text{anodic}} = -n F A J_{\text{Red}} > 0\)).softpotato.analytical.voltammetry: Correctedrandles_sevcik,randles_sevcik_irreversible, andrandles_sevcik_quasito return negative peak currents for cathodic sweeps and positive peak currents for anodic sweeps.softpotato.analytical.step: Corrected double potential step chronoamperometry (cottrell_step) so that forward reduction yields negative current and reverse oxidation yields positive current.softpotato.analytical.secm: Corrected SECM tip current calculation (secm_tip_current) to produce negative currents for reduction and positive currents for oxidation.softpotato.analytical.hydrodynamics: Corrected RRDE collection current (ring_collection_current) so that cathodic disk currents (\(I_{\text{disk}} < 0\)) produce positive anodic ring collection currents (\(I_{\text{ring}} = -N \cdot I_{\text{disk}} > 0\)).softpotato.analytical.fitting: Updated curve fitting routines (fit_cottrell,fit_randles_sevcik,fit_levich) to infer polarity from experimental data and robustly fit signed currents.- Updated unit test assertions across
tests/test_analytical_voltammetry.py,tests/test_analytical_step.py,tests/test_analytical_hydrodynamics.py, andtests/test_analytical_secm.py. - Fixed Faradaic current equation sign in the Cottrell tutorial notebook (
examples/cottrell.ipynb), ensuring the formula reflects positive oxidation current (\(I = n F A J_{\text{surface}}\)). - Corrected terminology in the Cottrell tutorial describing the process as a one-electron oxidation.
- Refined LaTeX math formatting and Markdown rendering in
examples/cottrell.ipynbfor consistency.
Added¶
- Interactive Cyclic Voltammetry Tutorial (
examples/cyclic_voltammetry.ipynb): - Added comprehensive interactive tutorial demonstrating 1D simulation of cyclic voltammetry with reversible electron transfer (\(O + e^- \rightleftharpoons R\)) under Nernstian equilibrium.
- Implemented dynamic triangular potential sweep waveform generator with forward cathodic and reverse anodic sweeps.
- Coupled time-dependent surface concentration boundary conditions to
ScipyIVPSolver(Method of Lines). - Visualized spatio-temporal concentration distributions across the diffusion layer at characteristic scan milestones (initial, cathodic peak, switching vertex, anodic peak, final).
- Validated simulated voltammetric response against theoretical diagnostic criteria: Randles–Ševčík peak current equation and peak potential separation (\(\Delta E_p \approx 57\text{--}59\text{ mV}\)).
- Linked notebook into documentation suite (
docs/examples/cyclic_voltammetry.ipynb). - CI/CD Quality & Automation Enhancements:
- Enhanced GitHub Actions CI workflow (
.github/workflows/ci.yml) to automatically apply Ruff lint fixes and code formatting viastefanzweifel/git-auto-commit-action. - Added
[tool.ruff]section inpyproject.tomlwithextend-excludeconfiguration for documentation build artifacts and example notebooks.
Changed¶
- Documentation & Metadata:
- Enhanced installation documentation (
docs/installation.rst) with detailed setup instructions for PyPI (pip), GitHub bleeding-edge installation, source development environments, and optional dependency extras ([test],[docs],[dev]). - Updated author contact email to
oliver.rdz@softpotato.xyzinpyproject.toml.
[3.1.0] - 2026-10-01¶
Milestone 1 Release: Analytical Equations, Benchmarking & Parameter Fitting¶
Soft Potato 3.1.0 delivers Milestone 1 of the strategic development roadmap, introducing a comprehensive suite of closed-form and empirical electrochemical equations (softpotato.analytical), automated numerical solver verification and benchmarking (softpotato.analytical.benchmark), non-linear least-squares parameter estimation and regression (softpotato.analytical.fitting), centralized physical and electrochemical constants (softpotato.constants), and an interactive Cottrell tutorial notebook (examples/cottrell.ipynb).
Removed¶
- Removed previous tutorial notebooks and documentation entries ahead of creating a redesigned tutorial suite.
Added¶
- Interactive Cottrell Chronoamperometry Tutorial (
examples/cottrell.ipynb): - Redesigned and refactored Cottrell chronoamperometry tutorial demonstrating 1D potential-step simulation with Soft Potato 3.1.
- Showcases problem formulation with
DiffusionProblem, Method of Lines stiff adaptive integration viascipy_ivp, spatio-temporal concentration profile verification against analytical error-function theory (step_concentration_profile), Faradaic current calculation and Cottrell plot analysis (cottrell), automated solver benchmarking (compute_error_metrics), and parameter estimation (fit_cottrell). - Integrated into Read the Docs documentation suite (
docs/examples/cottrell.ipynb) and automated CI test execution vianbmake. - Simulation Benchmarking Suite (
softpotato.analytical.benchmark): - Introduced dedicated automated solver benchmarking and verification submodule (
softpotato.analytical.benchmark) resolving Issue #17. - Added standardized error metrics calculation (
compute_error_metrics) returningBenchmarkMetricswith RMSE, maximum pointwise absolute error (\(L_\infty\)), discrete relative \(L_2\) error norm, mean absolute error (MAE), and zero-division-protected relative error metrics. - Added empirical order of convergence estimator (
estimate_convergence_order) via log-log linear regression returning order \(p\) and \(R^2\). - Added spatial discretization convergence verification (
verify_spatial_convergence) confirming expected second-order \(\mathcal{O}(\Delta x^2)\) convergence across grid refinement \(\Delta x\) withConvergenceResult. - Added temporal discretization convergence verification (
verify_temporal_convergence) confirming theoretical convergence rates (second-order \(\mathcal{O}(\Delta t^2)\) for Crank–Nicolson, first-order \(\mathcal{O}(\Delta t)\) for backward-Euler BTCS) with optional fine-step self-convergence baselining. - Added canonical Fourier sine diffusion decay benchmark (
run_fourier_decay_benchmark) with exact time-exponential decay and analytical interfacial flux validation. - Added planar Cottrell chronoamperometry potential step benchmark (
run_cottrell_benchmark) evaluating semi-infinite diffusion concentration fields (\(c(x, t) = c^* \text{erf}(x / 2\sqrt{Dt})\)) and Cottrell current transients. - Added total mass conservation benchmark (
run_mass_conservation_benchmark) verifying integral mass invariance under zero-flux Neumann boundary conditions. - Added single benchmark dispatcher (
run_benchmark) and multi-solver comparative suite runner (run_benchmark_suite) with formatted ASCII tabular summary reporting viaBenchmarkSuiteResult.summary(). - Re-exported all benchmark functions and result dataclasses in
softpotato.analyticaland top-levelsoftpotato. - Added comprehensive test suite in
tests/test_analytical_benchmark.pywith 27 tests covering error metrics, convergence verification, all standard benchmarks across solvers, and dispatcher utilities. - Documented
softpotato.analytical.benchmarkin Sphinx API reference (docs/api.rst). - Parameter Fitting & Experimental Data Analysis (
softpotato.analytical.fitting): - Introduced dedicated parameter estimation and regression submodule (
softpotato.analytical.fitting) resolving Issue #16. - Added general bounded non-linear least-squares fitting engine (
fit_curve) with sensitive tolerances for electrochemical micro- and nano-currents, parameter covariance, correlation matrix, Student's \(t\) confidence intervals, \(R^2\), adjusted \(R^2\), RMSE, and reduced \(\chi^2\). - Added ordinary and zero-intercept linear regression engine (
fit_linear) with exact analytical standard errors and confidence intervals. - Added Cottrell chronoamperometry fitter (
fit_cottrell) supporting linear (\(I \text{ vs. } t^{-1/2}\)) and non-linear (\(I(t)\)) regression with optional background current estimation returningCottrellFitResult. - Added Randles–Ševčík voltammetry fitter (
fit_randles_sevcik) for reversible and irreversible electron transfer returningRandlesSevcikFitResult. - Added RDE Levich analysis fitter (
fit_levich) supporting linear and non-linear optimization with dualomega/rpmrotation units returningLevichFitResult. - Added RDE Koutecký–Levich analysis fitter (
fit_koutecky_levich) supporting both linearized (\(1/I \text{ vs. } \omega^{-1/2}\)) and direct non-linear current regression returningKouteckyLevichFitResult. - Added high-field Tafel kinetics fitter (
fit_tafel) returningTafelFitResult. - Added full-range non-linear Butler–Volmer fitter (
fit_butler_volmer) simultaneously optimizing \(I_0\), \(\alpha\), and equilibrium potential offset returningButlerVolmerFitResult. - Added microdisc transient chronoamperometry fitter (
fit_microdisc_transient) with Shoup–Szabo and Mahon–Oldham models returningMicrodiscFitResult. - Added SECM approach curve feedback fitter (
fit_secm_approach) simultaneously estimating insulator ratio \(RG\), vertical positioning offset \(d_{\text{offset}}\), and substrate kinetics returningSECMApproachFitResult. - Implemented typed dataclasses for each technique inheriting from base
FitResult. - Re-exported all fitting functions and result dataclasses in
softpotato.analyticaland top-levelsoftpotato. - Added comprehensive test suite in
tests/test_analytical_fitting.pywith 19 tests. - Documented
softpotato.analytical.fittingin Sphinx API reference (docs/api.rst). - Scanning Electrochemical Microscopy (SECM) Approach Curves (
softpotato.analytical.secm): - Introduced dedicated SECM probe approach curve analytical submodule (
softpotato.analytical.secm). - Added Lefrou and Cornut analytical approximation for steady-state normalized tip current over conductive substrates (
secm_approach_positive_feedback) supporting variable normalized distance \(L = d/a\) and insulator radius ratio \(RG = r_g/a\). - Added Lefrou and Cornut analytical approximation for steady-state normalized tip current over inert insulating substrates (
secm_approach_negative_feedback) modeling hindered diffusion across all \(L\) and \(RG > 1\). - Added unified SECM approach curve model (
secm_approach_curve) supporting arbitrary first-order heterogeneous substrate kinetics (\(\kappa = \Lambda = ka/D \ge 0\)), smoothly interpolating between pure negative feedback (\(\kappa = 0\)) and pure positive feedback (\(\kappa \to \infty\)). - Added Saito steady-state limiting current calculation at infinite distance (
secm_limiting_current_infinite) for microdisk electrodes (\(i_{T,\infty} = 4 n F D c^* a\)). - Added dimensional tip current calculation in Amperes (
secm_tip_current) with IUPAC cathodic/anodic sign convention support. - Re-exported all SECM analytical functions at
softpotato.analyticaland top-levelsoftpotato. - Added comprehensive unit test suite in
tests/test_analytical_secm.pywith 21 tests and verified doctests. - Documented
softpotato.analytical.secmin Sphinx API reference (docs/api.rst). - Microelectrode & Ultramicroelectrode (UME) Models (
softpotato.analytical.microelectrodes): - Introduced dedicated microelectrode and ultramicroelectrode analytical submodule (
softpotato.analytical.microelectrodes). - Added Saito steady-state diffusion-limited current equation (
microdisc_limiting_current) for circular inlaid microdiscs (\(I_{\text{lim}} = 4 n F D c^* a\)). - Added Shoup and Szabo full-time chronoamperometric transient approximation (
microdisc_transient) for inlaid microdiscs spanning planar Cottrell decay to Saito steady state with \(<0.6\%\) relative error. - Added Mahon and Oldham analytical piecewise chronoamperometric transient model (
mahon_oldham_transient) for inlaid microdiscs with \(<0.02\%\) relative error across intermediate times. - Added hemispherical microelectrode steady-state diffusion-limited current (
microhemisphere_limiting_current) on an insulator (\(I_{\text{lim}} = 2 \pi n F D c^* r\)). - Added spherical microelectrode steady-state diffusion-limited current (
microsphere_limiting_current) in bulk solution (\(I_{\text{lim}} = 4 \pi n F D c^* r\)). - Added quasi-steady-state microband electrode diffusion-limited current (
microband_limiting_current) with logarithmic time decay (\(I_{\text{lim}}(t) = 2 \pi n F D c^* l / \ln(0.64 D t / w^2)\)). - Re-exported all microelectrode analytical functions at
softpotato.analyticaland top-levelsoftpotato. - Added comprehensive unit test suite in
tests/test_analytical_microelectrodes.pywith 20 tests and complete doctests. - Documented
softpotato.analytical.microelectrodesin Sphinx API reference (docs/api.rst). - Voltammetry & Kinetic Diagnostics (
softpotato.analytical.voltammetry): - Introduced voltammetric peak current and kinetic diagnostic submodule (
softpotato.analytical.voltammetry). - Added classical Randles–Ševčík peak current equation for reversible planar diffusion (
randles_sevcik) supporting cathodic and anodic sweeps with vectorization across scan rates. - Added irreversible Randles–Ševčík peak current equation (
randles_sevcik_irreversible) supporting variable transfer coefficient \(\alpha\) and stoichiometric electron count \(n_\alpha\). - Added quasi-reversible peak current approximation (
randles_sevcik_quasi) transitioning smoothly between reversible and irreversible limits via Matsuda–Ayabe shape factor \(K(\Lambda, \alpha)\). - Added Nicholson kinetic diagnostic method (
nicholson_psi) supporting forward calculation of peak separation \(\Delta E_p\), inverse estimation of dimensionless rate parameter \(\Psi\) (Swaddle, Lavagnini, and tabulated root-finding), and direct extraction of standard heterogeneous rate constant \(k^0\). - Added Matsuda–Ayabe reversibility parameter calculation (
matsuda_ayabe_lambda) and zone classification (matsuda_ayabe) returning structured dataclass (MatsudaAyabeResult). - Added irreversible peak potential shift diagnostics with scan rate (
peak_potential_irreversible). - Re-exported all voltammetry functions and dataclasses at
softpotato.analyticaland top-levelsoftpotato. - Added comprehensive test suite in
tests/test_analytical_voltammetry.pywith 23 tests and complete docstring examples. - Documented
softpotato.analytical.voltammetryin Sphinx API reference (docs/api.rst). - Thermodynamics & Interfacial Kinetics (
softpotato.analytical.kinetics): - Introduced thermodynamic and heterogeneous interfacial kinetics submodule (
softpotato.analytical.kinetics). - Added Nernst equilibrium electrode potential equation (
nernst/nernst_potential) supporting single-ratio (\(c_{\text{Ox}} / c_{\text{Red}}\)) or separate concentration arguments, with asymptotic \(\pm\infty\) limit handling. - Added equilibrium concentration ratio inverter (
nernst_ratio) and numerically stable species concentration distributor (nernst_equilibrium_concentrations) leveragingscipy.special.expit. - Added exchange current density (
exchange_current_density) and total exchange current (exchange_current) scaling with electrode area. - Added charge-transfer activation resistance calculation (
charge_transfer_resistance). - Added Butler–Volmer equation (
butler_volmerandbutler_volmer_current_density) supporting activation control, mass-transport/surface concentration corrections (\(c_i(0) / c_i^*\)), and IUPAC vs polarographic sign conventions. - Added low-overpotential linear Butler–Volmer approximation (
butler_volmer_linear). - Added theoretical Tafel slope equation (
tafel_slope) for anodic and signed cathodic branches. - Added high-overpotential Tafel current approximation (
tafel) with automatic branch detection (branch='auto') and overpotential inversion (tafel_overpotential). - Added diagnostic linear Tafel regression analysis (
tafel_analysis) returning structured dataclass (TafelResult) with extracted \(I_0\), Tafel slope \(b\) (in V/dec and mV/dec), apparent transfer coefficient \(\alpha\), \(R^2\), regression standard errors, and standard rate constant \(k^0\). - Re-exported all kinetics functions and dataclasses at
softpotato.analyticaland top-levelsoftpotato. - Added comprehensive unit test suite in
tests/test_analytical_kinetics.pywith 27 tests and verified doctests. - Documented
softpotato.analytical.kineticsin Sphinx API reference (docs/api.rst). - Hydrodynamics & Convection Equations (
softpotato.analytical.hydrodynamics): - Introduced hydrodynamic convective-diffusion equations submodule (
softpotato.analytical.hydrodynamics). - Added Levich equation (
levich) for convective mass-transport limiting current at a Rotating Disk Electrode (RDE) with dual angular velocity (omegain rad/s) and rotational frequency (rpm) input support. - Added theoretical Levich slope parameter utility (
levich_constant) and Nernst stagnant diffusion layer thickness calculation (nernst_diffusion_layer). - Added Koutecký–Levich equation (
koutecky_levich) for mixed kinetic and mass-transfer limitation, accepting explicit kinetic current (\(I_K\)), heterogeneous rate constant (\(k\)), and rotation speeds. - Added diagnostic Koutecký–Levich linear regression analysis (
koutecky_levich_analysis) extracting kinetic current (\(I_K\)), rate constant (\(k\)), Levich constant (\(B\)), estimated diffusivity (\(D\)), and \(R^2\). - Added exact closed-form Albery–Bruckenstein theoretical collection efficiency (
collection_efficiency) for Rotating Ring-Disk Electrodes (RRDE) evaluated analytically via hydrodynamic function \(F(\theta)\). - Added unshielded and shielded ring limiting currents (
ring_limiting_current), ring collection currents for disk-generated products (ring_collection_current), and geometric shielding factors (shielding_factor). - Added unified RRDE solver (
rotating_ring_disk) returning a structured dataclass (RRDEResult) with complete geometric and current parameters. - Added rotational speed conversion utilities (
rpm_to_rad_sandrad_s_to_rpm). - Re-exported all hydrodynamic functions and dataclasses at
softpotato.analyticaland top-levelsoftpotato. - Added comprehensive test suite in
tests/test_analytical_hydrodynamics.pywith 100% statement coverage, benchmarked against commercial Pine RRDE geometries and tutorial numerical simulation data. - Documented
softpotato.analytical.hydrodynamicsin Sphinx API reference (docs/api.rst). - Transient Diffusion & Potential Step Equations (
softpotato.analytical.step): - Introduced dedicated analytical equations subpackage (
softpotato.analytical.step). - Added planar Cottrell equation (
cottrell) for semi-infinite linear diffusion chronoamperometry. - Added spherical Cottrell equation (
cottrell_spherical) for spherical electrodes, hanging mercury drops, and hemispherical microelectrodes with long-time steady-state convergence. - Added double potential step chronoamperometry reversal transient (
cottrell_step) with diagnostic current ratio verification (\(-I(2\tau)/I(\tau) = 1 - 1/\sqrt{2} \approx 0.292893\)) and unequal diffusion coefficient (\(D_{\text{Red}} \neq D_{\text{Ox}}\)) support. - Added Anson equation (
anson) for single- and double-step chronocoulometry cumulative charge transients, supporting double-layer charging (\(Q_{\text{dl}}\)) and reactant surface excess (\(\Gamma\)). - Added Sand equation for chronopotentiometry transition time (
sand_transition_time), time-dependent surface concentration depletion (sand), and reversible chronopotentiometric wave potential (sand_potential). - Added cylindrical microelectrode chronoamperometry (
cottrell_cylinder) implementing Aoki's full-range approximation and Oldham's rational Padé approximant across all dimensionless times \(\theta\). - Added exact spatial concentration distribution (
step_concentration_profile) and diffusion flux profile (step_flux_profile) for analytical solver verification. - Re-exported all step equations and the
analyticalsubpackage at the top level ofsoftpotato. - Added comprehensive test suite in
tests/test_analytical_step.pycross-validating analytical solutions againstScipyIVPSolverand Sphinx documentation indocs/api.rst. -
Centralized Physical & Electrochemical Constants (
softpotato.constants): -
Introduced standard electrochemical constants: Faraday constant (
FARADAY), molar gas constant (GAS_CONSTANT), and standard thermodynamic temperature (STANDARD_TEMPERATURE). - Added shorthand aliases:
F,R, andT_STD. - Added foundational physical constants from CODATA / 2019 SI via
scipy.constants:AVOGADRO,BOLTZMANN,ELEMENTARY_CHARGE, andVACUUM_PERMITTIVITY. - Re-exported all constants and aliases at the top level of
softpotato. - Added unit test suite in
tests/test_constants.pyand Sphinx API documentation indocs/api.rst.
[3.0.0] - 2026-09-27¶
Stable Baseline Release: 1D Diffusion Solvers, SciPy Method of Lines & Benchmark Suite¶
Soft Potato 3.0.0 is the official stable baseline release following the ground-up architecture reboot. This release finalizes the numerical solver module (softpotato.solver), integrating the stiff scipy.integrate.solve_ivp Method of Lines integration alongside classical tridiagonal finite difference schemes, analytical validation benchmarks, and a publication-quality suite of interactive electrochemical tutorials.
Added¶
- Interactive Tutorials & Validation Notebooks (
examples/): - Cottrell Chronoamperometry with
solve_ivp(examples/cottrell_solve_ivp_tutorial.ipynb):- Simulates the Cottrell potential-step experiment using Soft Potato's adaptive
solve_ivpsolver and benchmarks against the analytical Cottrell equation.
- Simulates the Cottrell potential-step experiment using Soft Potato's adaptive
- Cyclic Voltammetry with Nernst Kinetics (
examples/cyclic_voltammetry_solve_ivp_tutorial.ipynb):- Simulates reversible cyclic voltammetry using
solve_ivp, visualizes spatio-temporal concentration profiles, validates peak currents against the Randles–Ševčík equation across scan rates, and evaluates diagnostic reversibility criteria.
- Simulates reversible cyclic voltammetry using
- Cyclic Voltammetry with Butler–Volmer Kinetics (
examples/cyclic_voltammetry_butler_volmer_tutorial.ipynb):- Simulates cyclic voltammetry under Butler–Volmer quasi-reversible kinetics with unequal diffusion coefficients (\(D_{\text{Red}} \neq D_{\text{Ox}}\)) using second-order ghost-node flux discretization and benchmarks against Nicholson theory.
- Rotating Disk Electrode (RDE) Voltammetry with Levich Analysis (
examples/rde_cyclic_voltammetry_solve_ivp_tutorial.ipynb):- Simulates RDE cyclic voltammetry with Nernst kinetics using the Nernst stagnant diffusion layer approximation (\(\delta = 1.61 D^{1/3} \nu^{1/6} \omega^{-1/2}\)). Demonstrates the transition from transient peaks to steady-state waves across scan rates and validates limiting currents against the Levich equation.
- RDE Voltammetry with Butler–Volmer Kinetics & Koutecký–Levich Analysis (
examples/rde_butler_volmer_koutecky_levich_tutorial.ipynb):- Simulates RDE cyclic voltammetry for an oxidation under IUPAC convention with Butler–Volmer kinetics using the Nernst diffusion layer approximation (\(\delta = 1.61 D^{1/3} \nu^{1/6} \omega^{-1/2}\)). Demonstrates kinetic shifts via normalized voltammograms (\(I/I_L\)), validates limiting currents against the Levich equation, and extracts \(k_0\) and \(\alpha\) using Koutecký–Levich and Tafel analysis.
- Project Roadmap (
ROADMAP.mdanddocs/roadmap.md): - Formulated and published strategic milestone roadmap for the 3.x series defining future backwards-compatible feature additions: Milestone 1: Grids (
3.1.0), Milestone 2: Reactions (3.2.0), and Milestone 3: Techniques (3.3.0). - Core Solver Enhancements (
softpotato.solver): - Implemented runtime option overrides via
**kwargsinBaseSolver.solve(), allowing parameters such asdt,method,rtol, andatolpassed at call time to take precedence over constructor defaults. - Added comprehensive parameter docstrings with type specifications across all solver implementations.
- Added dedicated solver reference table in
docs/api.rstsummarizing available methods and default options. - CI/CD Quality & Automation Enhancements (
.github/workflows/ci.yml): - Added dedicated GitHub Actions jobs for code formatting and lint verification (
ruff). - Added static type checking job (
mypy). - Added automated execution and testing of all Jupyter example notebooks via
nbmake(pytest -v --nbmake examples/). - Added test coverage reporting with
pytest-covand docstring testing with--doctest-modules. - Added automated package build verification and distribution metadata checks (
python -m build && twine check). - Sphinx Documentation Styling:
- Added custom stylesheet
docs/_static/custom.cssfor consistent presentation. - Configured
IPython.sphinxext.ipython_console_highlightingindocs/conf.pyfor reliable syntax highlighting of Jupyter notebook cells on Read the Docs.
Changed¶
- Promoted package version to
3.0.0and PyPI classifier toDevelopment Status :: 5 - Production/Stableinpyproject.toml. - Stabilized the
softpotato.solvermodule as the official v3.0.0 baseline. - Streamlined README.md:
- Replaced verbose quickstart with minimal 1D diffusion example using
scipy_ivp. - Added structured Tutorials & Examples table indexing all five interactive notebooks.
- Removed pre-release rewrite warning banner.
Fixed¶
- Fixed Python 3.10
TypeError: ABCMeta.__new__() got multiple values for argument 'name'duringBaseSolversubclass registration via_BaseSolverMetametaclass. - Fixed LaTeX/MathJax math delimiters rendering across Jupyter notebook tutorials and documentation pages on Read the Docs.
- Fixed Ruff formatting and lint violations across tutorials and source files.
Removed¶
- Removed legacy preliminary notebook
examples/1d_diffusion_comparison.ipynb. - Removed redundant
.github/workflows/docs.ymlworkflow file in favor of direct Read the Docs integration. - Removed temporary repository scaffolding script
scaffold.sh.
[3.0.0a1] - 2026-09-23¶
Complete Architecture Reboot & 1D Numerical Diffusion Solvers¶
Ground-up redesign and modern reimplementation of Soft Potato (v3.0.0a1), introducing a clean repository foundation, modernized packaging, Sphinx documentation with Read the Docs and GitHub Actions CI workflows, a unified numerical solver framework for multi-species 1D diffusion and reaction-diffusion systems (softpotato.solver), a comprehensive test suite with analytical validation, and interactive benchmark tutorials.
Added¶
- 1D Numerical Diffusion Solvers Framework (
softpotato.solver): -
Implemented
DiffusionProblemformulation for 1D multi-species chemical diffusion and reaction-diffusion systems:\[ \frac{\partial c_i}{\partial t} = D_i \frac{\partial^2 c_i}{\partial x^2} + R_i(\mathbf{c}, x, t) \]- Monotonically increasing 1D spatial grid validation with uniform step size detection (
dxproperty). - Multi-species support with strict validation for positive diffusion coefficients (\(D_i > 0\)).
- Flexible initial conditions supporting constant scalar concentrations, 1D NumPy profile arrays, or spatial callables \(f(x)\).
- Pluggable homogeneous reaction kinetics term \(R_i(\mathbf{c}, x, t)\) returning reaction rates per species.
- Implemented
BoundaryConditionclass and factory constructors: DirichletBC: Fixed concentration boundary conditions (\(c = \text{value}\)), supporting static float values or time-dependent callables \(f(t)\).NeumannBC: Concentration gradient boundary conditions (\(\partial c / \partial x = \text{value}\)), supporting static float values or time-dependent callables \(g(t)\).- Implemented
SolverResultcontainer: - Standardized simulation output holding time array \(t\) (\(N_t\)), grid coordinates \(x\) (\(N_x\)), and per-species 2D concentration arrays (\(N_t \times N_x\)).
- Dict-like shorthand indexing (
result["A"]) and species listing (result.species). - Automated surface flux computation at the left boundary \(x=0\): \(J_i(t) = -D_i \left.\frac{\partial c_i}{\partial x}\right|_{x=0}\) using second-order forward finite differences.
- Status reporting with
success,message, andraw_output. - Implemented
BaseSolverabstract base class: - Dynamic solver registry with auto-registration on subclassing (
BaseSolver, name="...") and@register_solver(name)decorator. - Integrated
solve()pipeline orchestrating pre-run input validation (validate), numerical integration dispatch (_run_solver), and post-processing flux calculation (_post_process). - Solver factory function
get_solver(name, **kwargs)and discovery functionlist_solvers(). - Implemented four numerical diffusion solvers:
- Method of Lines (
ScipyIVPSolver, aliases:"scipy_ivp","solve_ivp"): - Spatial semi-discretization into an ODE system integrated via
scipy.integrate.solve_ivp. - Default stiff integrator using the implicit 5th-order Runge-Kutta
Radaumethod, with support forBDF,RK45,RK23, andLSODA. - Direct coupling of homogeneous reaction kinetics \(R_i(\mathbf{c}, x, t)\) and dynamic Dirichlet/Neumann boundary conditions.
- Crank-Nicolson (
CrankNicolson, aliases:"crank_nicolson","crank-nicolson"): - Unconditionally stable second-order in time and space implicit finite difference method (\(\mathcal{O}(\Delta t^2, \Delta x^2)\)).
- Efficient tridiagonal system solution via
scipy.linalg.solve_banded(\(O(N)\) Thomas algorithm). - Handles both Dirichlet and second-order central difference Neumann boundary conditions, plus homogeneous reaction term coupling.
- Implicit Finite Difference (
ImplicitFiniteDifference, aliases:"implicit","btcs"): - Backward-Time Central-Space (BTCS) unconditionally stable implicit scheme (\(\mathcal{O}(\Delta t, \Delta x^2)\)).
- Tridiagonal matrix solver via
scipy.linalg.solve_bandedsupporting Dirichlet and Neumann boundary conditions. - Explicit Finite Difference (
ExplicitFiniteDifference, aliases:"explicit","ftcs"): - Forward-Time Central-Space (FTCS) explicit scheme (\(\mathcal{O}(\Delta t, \Delta x^2)\)).
- Strict Courant-Friedrichs-Lewy (CFL) stability enforcement (\(\Delta t \le \frac{\Delta x^2}{2 D_{\max}}\)) with configurable auto-substepping (
auto_substep=True) or explicit error raising. - Explicit
__init__signatures, typed parameters, and NumPy docstrings across all solver classes (dtfor FTCS/BTCS/Crank-Nicolson;method,rtol,atolfor SciPy IVP) ensuring full option visibility in Sphinx autodoc and IDE autocompletion. - Top-Level Package API (
softpotato): - Re-exported core solver classes (
BaseSolver,BoundaryCondition,DiffusionProblem,DirichletBC,NeumannBC,SolverResult,get_solver,list_solvers) insoftpotato/__init__.py. - Exposed module version
__version__ = "3.0.0a1". - Testing Suite (
tests/): - Added 15 comprehensive unit tests in
tests/test_solvers.py: - Registry and alias lookup validation (
test_solver_registry). - Custom solver extensibility via subclassing and
@register_solver(test_user_defined_solver_subclass,test_user_defined_solver_decorator). - Analytical benchmark test against the exact Fourier sine decay solution (\(c(x, t) = \sin(\pi x / L) e^{-D (\pi/L)^2 t}\)) verifying \(< 5\times 10^{-3}\) maximum error across all 4 solvers (
test_analytical_dirichlet_benchmark). - Total mass conservation test under zero-flux Neumann boundary conditions (\(< 0.1\%\) relative variation) across all 4 solvers (
test_neumann_mass_conservation). - CFL stability validation and error checking for the explicit solver (
test_explicit_cfl_validation). - Multi-species diffusion simulation with differential diffusion coefficients (
test_multi_species_diffusion). - First-order homogeneous reaction-diffusion kinetics (\(R_A = -k c_A\)) verified against analytical exponential decay (
test_reaction_diffusion). - Input validation for non-monotonic grids and inverted time spans (
test_input_validation). - Added baseline import and version smoke test
tests/test_basic.py. - Documentation & Sphinx Framework (
docs/): - Configured Sphinx documentation with Read the Docs theme (
sphinx_rtd_theme),autodoc,napoleon,viewcode,mathjax,nbsphinx, andmyst_parser. - Added native Markdown support via
myst_parserwithdollarmathextension for MathJax rendering of inline and display LaTeX math equations. - Symlinked root
CHANGELOG.mdtodocs/changelog.mdand addedDevelopment & Releasestoctree section indocs/index.rstto publish the changelog directly on Read the Docs. - Added a dedicated "Solvers and Supported Options" quick-reference table in
docs/api.rstsummarizing all solvers, registered aliases, configuration parameters, and default values. - Added main landing page (
docs/index.rst), installation guide (docs/installation.rst), and API reference (docs/api.rst). - Configured Read the Docs build specification (
.readthedocs.yaml) targeting Ubuntu 24.04 and Python 3.11. - Added local documentation build automation scripts (
docs/Makefile,docs/make.bat). - Added GitHub Actions workflow (
.github/workflows/docs.yml) for automated documentation builds and ReadTheDocs deployment. - Interactive Tutorials & Benchmarking (
examples/): - Added interactive tutorial notebook
examples/1d_diffusion_comparison.ipynb(and mirrored indocs/examples/1d_diffusion_comparison.ipynb): - Comparative study of FTCS, BTCS, Crank-Nicolson, and SciPy Method of Lines against the exact analytical solution.
- Demonstrations of numerical stability breakdown when exceeding the explicit CFL limit.
- Step-size convergence scaling analysis and solver execution time profiling.
- Project Infrastructure & Tooling:
- Configured standard
pyproject.tomlwith PEP 621 package metadata, runtime dependencies (numpy,scipy,matplotlib), test dependencies (pytest), docs dependencies (sphinx,sphinx-rtd-theme,sphinx-autodoc-typehints,nbsphinx,ipykernel,myst-parser), and dev configurations forruff,black, andmypy. - Added GitHub Actions CI workflow (
.github/workflows/ci.yml) matrix-testing across Python 3.10, 3.11, 3.12, and 3.13 on Ubuntu. - Configured root
.gitignorecovering Python cache files, virtual environments, build artifacts, and Jupyter checkpoint files. - Added open-source BSD 3-Clause license (
LICENSE). - Added automated scaffolding script
scaffold.sh. - Added clear development notice banner in
README.mdhighlighting the activev3.0.0a1architectural rewrite.
- Monotonically increasing 1D spatial grid validation with uniform step size detection (
Changed¶
- Refactored
README.md: - Added active rewrite warning banner for
v3.0.0a1. - Added comprehensive quickstart guide demonstrating 1D multi-species diffusion with
scipy_ivp. - Added overview table of built-in numerical solvers (Method of Lines, Crank-Nicolson, Implicit, Explicit).
- Added walkthrough on implementing and registering custom solvers with
BaseSolver. - Linked interactive tutorial notebooks and Read the Docs documentation.
- Enhanced solver option discovery and type inspection across the entire
softpotato.solversubpackage: - Added explicit typed
__init__constructor methods forExplicitFiniteDifference,ImplicitFiniteDifference,CrankNicolson, andScipyIVPSolverforwarding**optionstoBaseSolver. - Added NumPy-formatted
Parametersdocstrings across all solvers,BaseSolver.__init__,BaseSolver.solve, andget_solver. - Updated runtime option resolution in solver engines so
kwargspassed tosolve()dynamically override instance options. - Overhauled GitHub Actions CI workflow (
.github/workflows/ci.yml) into a parallel multi-job pipeline: - Dedicated
lint-and-formatjob runningruff check .andruff format --check .. - Dedicated
type-checkjob executing static type analysis withmypy src. - Expanded
testmatrix across Python 3.10, 3.11, 3.12, and 3.13 running unit tests, embedded docstring doctests (pytest --doctest-modules src tests/), statement test coverage (--cov=softpotato), and full Jupyter notebook execution (pytest --nbmake examples/). - Added
package-checkjob validating sdist and wheel build generation (python -m build) and PyPI metadata/README rendering (twine check dist/*). - Codebase formatting and type annotations:
- Applied
ruff formatacross all Python source modules, tests, markdown code snippets, and Jupyter notebook cells. - Alphabetized
__all__exports acrosssoftpotatoandsoftpotato.solver. - Migrated
Callabletyping import insoftpotato.solver.basetocollections.abc.Callable(PEP 585 / UP035). - Added typed scalar casting with
cast(Any, ic)inDiffusionProblem.get_initial_profilefor strictmypycompliance. - Removed unused imports in
tests/test_solvers.py(BoundaryCondition) andexamples/1d_diffusion_comparison.ipynb(NeumannBC). - Fixed undefined analytical reference
c_exact_benchin benchmark timing cell ofexamples/1d_diffusion_comparison.ipynb. - Updated
docs/conf.pyanddocs/index.rstto integratenbsphinxandmyst_parser, configuringsource_suffixfor both.rstand.md. - Updated
pyproject.tomlwith[tool.mypy]configuration and addedpytest-cov>=4.1.0,nbmake>=1.5.0, andmypy>=1.5.0to optional dependencies.
Fixed¶
- Fixed Python 3.10 class creation failure (
TypeError: ABCMeta.__new__() got multiple values for argument 'name') across all solvers by introducing_BaseSolverMetaonBaseSolverto safely extractnameandsolver_nameclass keyword arguments prior to delegating toABCMeta.__new__.
Removed¶
- Removed
.github/workflows/docs.yml(obsolete standalone workflow referencing non-existentreadthedocs/upload-action@v1; documentation builds and deployments are managed natively via Read the Docs GitHub webhook integration configured in.readthedocs.yaml). - Removed legacy pre-3.0 codebase (monolithic
softpotato.core,softpotato.analytical,softpotato.geometry,softpotato.simulate,softpotato.techniques, andsoftpotato.kinetics) to establish a modular, maintainable, and rigorously tested foundation.
[3.0.0rc1] - 2026-09-20 [Yanked / Pre-Rewrite]¶
Release Candidate 1¶
First release candidate (rc1) for Soft Potato 3.0.0, delivering an end-to-end simulation MVP for Cyclic Voltammetry alongside the core mechanisms, analytical solutions, and revised 4-stage development roadmap.
Added¶
- Core Module (
softpotato.core): - Implemented the
Speciesclass with strict CGS unit enforcement:- Diffusion coefficient (\(D\)) in \(\text{cm}^2/\text{s}\) (\(D \ge 0\)).
- Bulk concentration (\(c_{\text{bulk}}\)) in \(\text{mol}/\text{cm}^3\) (\(c_{\text{bulk}} \ge 0\), \(1\text{ mM} = 10^{-6}\text{ mol}/\text{cm}^3\)).
- Spatial concentration profile (\(c_{\text{profile}}\)) in \(\text{mol}/\text{cm}^3\).
- Ionic charge / valence number (\(z\)).
- Added strict parameter validation for non-negative values, non-empty names, and integer charge.
- Implemented profile memory management (
initialize_profileto allocate 1D NumPy arrays andresetto restore initial bulk conditions). - Added
__hash__method toSpeciesallowing instances to be used in sets and as dictionary keys (e.g., in stoichiometry mappings). - Implemented
ElectrochemicalReactionrepresenting interfacial electron transfer (\(O + n e^- \rightleftharpoons R\)) with strict validation forn_electrons,E0,kinetics, and stoichiometric coefficients. - Implemented
ChemicalReactionrepresenting homogeneous bulk reactions (\(\sum \nu_r R \rightleftharpoons \sum \nu_p P\)) with support for kinetics and stoichiometry. - Implemented
Mechanismcontainer orchestrating reactions and species, featuring:- Automatic species discovery and order preservation from reactions.
- Categorization into
e_reactions(electrochemical_reactions) andc_reactions(chemical_reactions). - Indexing by species name (
mech["O"]/mech.get_species) and reaction index (mech[0]). - Delegated profile initialization and reset across all species.
- Implemented centralized physical constants module (
softpotato.core.constants):FARADAY: Faraday constant (\(\approx 96485.33212\text{ C/mol}\)).GAS_CONSTANT: Molar gas constant \(R\) (\(\approx 8.3144626\text{ J/(mol}\cdot\text{K)}\)).STANDARD_TEMPERATURE: Standard temperature (\(298.15\text{ K}\)).
- Analytical Solutions (
softpotato.analytical): - Implemented closed-form, vectorized analytical solutions across modular subpackages:
- Potential Step & Chronocoulometry (
softpotato.analytical.techniques.step): cottrell: Transient current decay for planar diffusion.anson: Cumulative charge transient for chronocoulometry including double-layer (\(Q_{dl}\)) and adsorption (\(Q_{ads}\)) charges in Coulombs.spherical_cottrell: Transient current at a spherical electrode with area derived from radius \(r_0\).- Voltammetry (
softpotato.analytical.techniques.voltammetry): randles_sevcik: Peak current for reversible electron transfer.randles_sevcik_irreversible: Peak current for totally irreversible electron transfer.peak_potential_irreversible: Peak potential shift for totally irreversible electron transfer.- Microelectrode Geometries (
softpotato.analytical.geometry.microelectrodes): steady_state_microdisc: Saito equation for steady-state limiting current at an inlaid microdisc with radius \(a\).steady_state_microhemisphere: Steady-state limiting current at a microhemisphere electrode.- Hydrodynamics (
softpotato.analytical.geometry.hydrodynamics): levich: Mass-transport limiting current at a rotating disk electrode (RDE).koutecky_levich: Net steady-state current combining kinetic and mass-transport limitations.- Kinetics & Reversibility (
softpotato.analytical.kinetics.reversibility): nicholson_psi: Nicholson kinetic reversibility parameter \(\Psi\).- Reaction Mechanisms (
softpotato.analytical.kinetics.mechanisms): catalytic_current: Steady-state catalytic current for an \(EC'\) mechanism (with aliascatalytic_current_ec_prime).
- Potential Step & Chronocoulometry (
- Added top-level facade imports in
softpotato.analyticalfor direct access to all equations. - Simulation MVP (
softpotato.simulate,softpotato.geometry,softpotato.techniques,softpotato.kinetics): - Implemented the end-to-end numerical simulation pipeline for Cyclic Voltammetry:
GridABC andUniformGridrepresenting uniform 1D spatial discretization with strict CGS coordinates.ElectrodeABC andPlanarElectroderepresenting planar macroelectrodes with 1D spatial Laplacian differential operators.TechniqueABC andCyclicVoltammetrygenerating exact triangular potential waveforms and sampling parameters (\(dt\), duration).KineticsModelABC andButlerVolmerimplementing potential-dependent forward/backward heterogeneous rate constants and surface reduction flux.- Vectorized Explicit Finite Difference (EFD) engine (
explicit_diffuse_step) and surface flux boundary condition solver (update_surface_concentrations). - High-level
Solverorchestrator supporting automated CFL stability sub-stepping (auto_substep=True) with informativeUserWarning. SimulationResultdataclass storing time, potential, current, concentration profiles, and a built-in.plot()method.
- Added interactive tutorial notebook
examples/cv_simulation.ipynbdemonstrating end-to-end CV simulation, Butler-Volmer kinetics theory, and Randles-Sevcik benchmarking. - Added integration benchmark test
tests/test_cv_benchmark.pyvalidating simulated reversible peak current against analyticalrandles_sevcik(< 3% error). - Module Scaffolding:
- Established subpackage hierarchy:
softpotato.geometry: Grids (grids.py) and electrode geometries (electrodes.py).softpotato.simulate: PDE solvers (solver.py), explicit finite difference (efd.py), and implicit finite difference (ifd.py).softpotato.techniques: Electrochemical waveforms including voltammetry (voltammetry.py) and potential step (step.py).softpotato.kinetics: Pluggable kinetic models (in development).
- Testing & Quality Infrastructure:
- Added comprehensive test suite in
tests/test_core.pycoveringSpecies,ElectrochemicalReaction,ChemicalReaction, andMechanism(initialization, validations, memory allocations, property setters, representations, indexing, and stoichiometry matrix). - Configured
pyproject.tomlwith package metadata, runtime dependencies (numpy,scipy,matplotlib), test dependencies (pytest), and tool configurations forblack,ruff, andmypy. - Added GitHub Actions CI workflow (
.github/workflows/ci.yml) matrix testing across Python 3.10, 3.11, and 3.12. - Added root
.gitignorecovering Python cache directories, virtual environments, build artifacts, and editor settings. - Licensing & Project Metadata:
- Adopted the open-source BSD 3-Clause License (
LICENSE). - Added license metadata and PyPI classifier (
License :: OSI Approved :: BSD License) inpyproject.toml. - Documentation & Sphinx Framework (
docs/): - Configured Sphinx documentation with Read the Docs integration (
.readthedocs.yaml) using thesphinx_rtd_theme. - Added Sphinx configuration (
docs/conf.py) integratingautodoc,napoleon,mathjax,viewcode,todo,sphinx-math-dollar, andnbsphinx. - Added main landing page (
docs/index.rst), roadmap document (docs/roadmap.rst), and API reference structure (docs/api/index.rst). - Added Sphinx
.. warning::and.. todo::directives across all placeholder/scaffolding modules (geometry,simulate,techniques,kinetics) to clearly signal their development status in generated documentation. - Added
docs/Makefileanddocs/make.batbuild scripts for local documentation generation. - Added dedicated license page (
docs/license.rst) embedding the rootLICENSEfile into the Sphinx documentation table of contents. - Added automated
docsbuild validation job in GitHub Actions workflow (.github/workflows/ci.yml). - Interactive Tutorials & Examples (
examples/): - Added comprehensive tutorial notebook
examples/mechanisms.ipynbcovering mechanism definitions in Soft Potato 3.0:- Single-electron transfers (\(E\)).
- Chemical equilibria (\(C\)).
- Coupled EC and multi-step ECE mechanisms.
- Disproportionation pathways (ECE vs. DISP competition with multi-reactant/product stoichiometry, and bimolecular radical disproportionation \(2R \rightleftharpoons O + Z\)).
- Solver integration features (profile initialization
initialize_profiles, resetreset, dictionary indexing, and stoichiometry matrix inspection).
- Linked interactive tutorial notebook into Sphinx documentation via
docs/examples/mechanisms.nblink. - Dependencies (
pyproject.toml): - Added optional
docsdependency group (sphinx,sphinx-rtd-theme,sphinx-autodoc-typehints,nbsphinx,nbsphinx-link,ipython,ipykernel).
Changed¶
- Configured Black
target-version = ["py310"]inpyproject.tomlto ensure consistent AST checks across the Python 3.10–3.12 CI matrix. - Structured package exports in
softpotato/__init__.pyusing explicit__all__declarations. - Cleaned up docstrings in
src/softpotato/core/reactions.pyby removing redundantAttributes:sections to optimize Sphinx autodoc rendering. - Formatted
src/softpotato/core/reactions.pyandtests/test_core.pyto adhere strictly to Ruff formatting and lint rules.
Removed¶
- Removed legacy
src/softpotato/core/README.mdin favor of Sphinx documentation.