Zitao Ni

Ph.D. in Materials Science and Engineering

Session 04 Background: Full SPM Implementation & Voltage Coupling

Study Session #04: Full SPM Implementation & Voltage Coupling

Read this file to seamlessly continue learning in a new conversation
This file follows the note_specification.md standard
Teaching Mode: Zero-baseline friendly, all figures generated as PNG via matplotlib


1. Recap (Previously Learned)

1.1 Chapter 1: Electrochemistry Basics & OCV

Three SPM assumptions, parameter naming conventions, SOC & N/P ratio, OCV curves (Nernst + graphite tanh + NMC polynomial).

1.2 Chapter 2: Diffusion Equation (Fick’s Second Law)

Knowledge Point Key Points
Fick’s First Law J = −D·∂c/∂r
Fick’s Second Law (spherical) ∂c/∂t = D·[∂²c/∂r² + (2/r)·∂c/∂r]
Implicit Euler (I − DΔt·L)·c_new = c_old
Tridiagonal Matrix scipy solve_banded

1.3 Chapter 3: Butler-Volmer Kinetics — Just Completed

Knowledge Point Key Points
Overpotential η Extra driving force needed to cross the interface energy barrier
BV Forward j = j₀·[e^(αFη/RT) − e^(−(1−α)Fη/RT)]
j₀ Dependence j₀ = k·√c_e·√c_s·√(c_max−c_s), max at SOC=50%
arcsinh Inversion (α=0.5) η = (2RT/F)·arcsinh(j/2j₀)
Linear Approximation
Newton Iteration (α≠0.5) 3-step convergence, quadratic convergence rate
Independent Implementation bv_my.py, 0 nV difference vs model.py

1.4 Review of the Four SPM Equations

1
2
3
4
5
6
7
8
9
10
11
Loop 1 (outer): current → flux → overpotential → voltage

Current i_app

j = i_app / (a_s·L·F) ← current→flux (Ch1)

η = BV(j, c_s_surf) ← flux→overpotential (Ch3)
↓ ↑
c_s_surf ← diffusion updates c(r) ← concentration←diffusion (Ch2)

V = U(OCV) + η_p − η_n ← voltage coupling (this chapter)

You now possess all four SPM equations. This chapter’s task is to “connect them” so the model runs in full.


2. Current Code Status

2.1 File Inventory

File Purpose Status
spm/parameters.py Battery physical parameters + SOC auto-conversion Complete
spm/model.py SPM core engine (four equations + step + simulate) Exists, to be studied
learning/learning_notes_03_kinetics/bv_my.py Independent BV implementation Complete
learning/learning_notes_02_diffusion/diffusion_solver_my.py Independent diffusion solver Complete

SPMModel.__init__() Initialization Logic:

1
2
3
4
5
6
7
8
Function: SPMModel.__init__(params)
Purpose: Initialize the SPM simulation engine
Algorithm:
1. Store parameter object reference
2. Build radial grid r = linspace(0, R, Nr) for each electrode
3. Set initial concentration uniform at c_s_init for each electrode
4. Compute active specific surface area: a_s = 3 * eps_s / R
5. Pre-build tridiagonal diffusion matrix A_base for each electrode

step() Method Logic:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Function: step(i_app)
Purpose: Advance the SPM state by one time step dt
Algorithm:
1. Step 1 (Current → Flux):
j_n = -i_app / (a_s_n * L_n * F)
j_p = i_app / (a_s_p * L_p * F)
2. Step 2 (Flux → Overpotential):
eta_n = butler_volmer_overpotential(j_n, k_n, c_e, c_s_surf_n, ...)
eta_p = butler_volmer_overpotential(j_p, k_p, c_e, c_s_surf_p, ...)
3. Step 3 (Diffusion → Update Concentration):
Build RHS with surface flux boundary condition
Solve banded linear system for each electrode
4. Step 4 (Voltage Coupling):
V_cell = U_p + eta_p - U_n - eta_n
Returns: V_cell

simulate() Method Logic:

1
2
3
4
5
6
7
8
Function: simulate(t_end, i_app)
Purpose: Run a full discharge/charge simulation over t_end seconds
Algorithm:
1. n_steps = int(t_end / dt)
2. For k = 1 to n_steps:
a. V = step(i_app)
b. Record V, eta_n, eta_p, soc_n, soc_p, ...
3. Return results dictionary with time series arrays

2.3 Key Parameter Quick Reference

Parameter Value Meaning
i_app Typical 10 A/m² (1C) Applied current density (positive = discharge)
A_electrode 1.0 m² Electrode area
t_end 3600 s Typical simulation duration (1C = 1h)
dt 1.0 s Time step
Nr 50 Particle mesh points

3. This Session’s Learning Topics

Full SPM Implementation — Connecting Four Equations to Run a Simulation

The first three chapters separately learned the three “components” of SPM: OCV, Diffusion, and BV. This chapter’s task is to understand how they combine into a complete working engine.

Core Questions:

  1. How does step() connect the four equations within each Δt?
  2. How does c_s_surf from diffusion feed back to BV? How does η from BV form voltage?
  3. How does simulate() drive the entire simulation loop?
  4. How do we interpret the components of discharge/charge curves?

4. This Session’s Study Plan

4.1 Learning Objectives

  1. Understand SPM step()‘s four-step cyclic dataflow
  2. Master the voltage coupling equation V_cell = U_p + η_p − U_n − η_n
  3. Understand simulate()‘s loop structure and result recording
  4. Be able to run full simulations and interpret discharge curve components
  5. Understand the effect of different currents (C-rates) on voltage curves

4.2 Learning Path

1
2
3
4
5
6
7
8
9
A["Four-equation dataflow<br/>step() line-by-line reading"]

B["Voltage coupling<br/>Breakdown of V = U + η"]

C["simulate() loop<br/>Time advancement and state management"]

D["Run simulation<br/>Discharge/charge curves"]

E["C-rate sensitivity<br/>Behavior at different currents"]

4.3 Detailed Content

Part A: step() Four-Step Dataflow

SPM’s step() is the heart of the model — each call advances time by dt seconds:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Step 1: i_app → j_n, j_p
┌────────────────────────────────┐
│ j_n = −i_app / (a_s_n·L_n·F) │
│ j_p = i_app / (a_s_p·L_p·F) │
└────────────────────────────────┘

Step 2: j + c_s_surf → η
┌────────────────────────────────┐
│ η_n = BV(j_n, c_s_surf_n, ...) │
│ η_p = BV(j_p, c_s_surf_p, ...) │
└────────────────────────────────┘

Step 3: j → update c(r) (diffusion)
┌────────────────────────────────┐
│ Implicit Euler + tridiagonal solve│
│ Surface BC: D·(c_surf−c_near)/dr=j │
└────────────────────────────────┘
↓ ↑
new c_s_surf feeds back to next step's Step 2

Step 4: Voltage coupling
┌────────────────────────────────┐
│ V_cell = U_p + η_p − U_n − η_n │
└────────────────────────────────┘

Key insight: Step 3 updates c_s_surf, and this new c_s_surf is used in the next time step’s Step 2 as the BV input. This is the coupling between diffusion and BV — concentration changes affect overpotential through BV, and overpotential in turn affects voltage.

Part B: Voltage Coupling Equation

In SPM, the cell terminal voltage is composed of four terms:

$$V_{cell} = U_p(\text{SOC}_p) + \eta_p - U_n(\text{SOC}_n) - \eta_n$$

Term Meaning Sign During Discharge
U_p Cathode OCV ~4.0 V (varies with SOC)
U_n Anode OCV ~0.1 V (varies with SOC)
η_p Cathode overpotential < 0 (penalty)
η_n Anode overpotential > 0 (penalty)

During discharge:

$$V_{cell} = \underbrace{(U_p - U_n)}{\text{Ideal OCV}} ;-; \underbrace{(|\eta_p| + |\eta_n|)}{\text{Polarization loss}}$$

Overpotential is a “penalty term” — the larger the current, the larger the overpotential, and the lower the voltage.

Part C: simulate() Time Advancement

1
2
3
4
5
6
Loop structure: simulate() = step() × n_steps + result recording.

For each step:
1. Call step(i_app) — advance state by dt
2. Record V, eta_n, eta_p, soc_n, soc_p, ...
3. Self.time increments by dt

Part D: Generate Complete Discharge Curve

Use matplotlib to plot voltage vs time and decompose OCV and overpotential contributions on the same plot.

Subplot 1: V_cell vs time (complete discharge curve)
Subplot 2: Voltage breakdown — individual contributions of U_p, U_n, η_p, η_n
Subplot 3: SOC evolution — surface SOC vs average SOC (showing diffusion lag)

Part E: C-rate Sensitivity Analysis

Battery rate performance: voltage curve differences at various currents (C/5, C/2, 1C, 2C).

C-rate Current Discharge Time Overpotential Magnitude Voltage Level
C/5 Small 5h Small High (close to OCV)
1C Medium 1h Medium Medium
2C Large 30min Large Low (severe polarization)

4.4 Practice Tasks

# Task Related Code
1 Line-by-line understanding of step()‘s four-step flow model.py#step
2 Hand-derive voltage coupling formula (sign verification) model.py Step 4
3 Run full simulation, plot discharge curve model.py#simulate
4 Plot voltage breakdown (OCV + η individual contributions) Visualization
5 Run comparison simulations at different C-rates Parameter experiment
6 Understand η and c_s_surf evolution in the loop Data analysis

4.5 Generated Figures

spm_discharge.png (Discharge Curve · 3 Subplots)

Subplot 1: V_cell vs Time

  • X-axis: time (s), Y-axis: V
  • Mark discharge endpoint (cutoff voltage 2.5V or SOC=0)

Subplot 2: Voltage Breakdown

  • V_cell, U_p, U_n, η_p, η_n on the same plot
  • Label direction and magnitude of each contribution

Subplot 3: SOC Evolution

  • Surface SOC vs average SOC (one curve each for anode and cathode)
  • Label diffusion lag effect

crate_comparison.png (C-rate Comparison)

Subplot: Discharge curves at different C-rates overlaid

  • Label: higher rate → lower voltage, shorter discharge time

4.6 Preview Questions

  1. Why are the four steps in step() in this particular order? What would happen if diffusion were computed before BV?
  2. During discharge, η_n > 0 and η_p < 0. When substituted into V = U_p + η_p − U_n − η_n, do η_p and η_n affect voltage in the same or opposite direction?
  3. Why is the voltage curve significantly lower at high current than at low current? Besides overpotential, what other reasons are there?

5. Three-Chapter Summary: Your SPM Knowledge Graph

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌─────────────────────────────────────────────────────────────┐
│ The Four SPM Equations │
│ │
│ Equation ①: U(θ) — OCV curve │
│ Equation ②: ∂c/∂t — Diffusion in spherical particles │
│ Equation ③: j ↔ η — Butler-Volmer interface kinetics │
│ Equation ④: V_cell — Voltage coupling = Σ parts │
│ │
│ Coupling: c_s_surf changing → η changing → V changing │
│ C-rate: large current → large η → low V │
│ │
│ Missing from SPM: electrolyte concentration gradient, │
│ ohmic drop (→ SPMe / P2D supplements) │
└─────────────────────────────────────────────────────────────┘

6. Reference Index

Reference Chapter Content
[Brett] Ch2 §2.2-2.4 Cell potential calculation
[Brett] Ch1 §1.3 Thermodynamics & kinetics, overpotential
[Rechargeable] Ch1 §1.2.2 Electrode kinetics & polarization losses

Ready to begin Session 4. Start with Session 4.1: step() four-step dataflow.

0%