Zitao Ni

Ph.D. in Materials Science and Engineering

Course #02: Diffusion Equation (Fick's Second Law)

Course #02: Diffusion Equation (Fick’s Second Law)

Read this file to seamlessly resume learning in a new conversation
This file follows the note_specification.md standard
Teaching mode: Zero-basis friendly, all figures generated using matplotlib PNG


I. Prior Knowledge Review

1.1 Electrochemical Simulation Fundamentals

Electrochemical simulation = creating a “digital twin” of a battery — using mathematical equations to simulate internal battery processes on a computer:

  • During discharge: negative electrode deintercalates Li → Li⁺ traverses electrolyte → positive electrode intercalates Li
  • Electrons flow through external circuit to do work

1.2 SPM (Single Particle Model)

Core simplification: Collapse thousands of particles in each electrode into a single spherical particle.

Three assumptions:

  1. All particles behave identically → one sphere represents the entire electrode
  2. Neglect electrolyte concentration variation → c_e is uniform everywhere
  3. Uniform current distribution → each particle experiences the same current

Capability boundaries:

  • Can predict voltage-time curves (discharge curves)
  • Can predict lithium concentration distribution inside particles
  • Cannot accurately predict high current operation (lacks electrolyte gradients)

1.3 Parameter Naming Convention

self.{physical_quantity}_{phase}_{position}, e.g.:

  • c_s_max_n = concentration-solid-max-negative = negative electrode solid-phase maximum lithium concentration
  • D_s_p = diffusivity-solid-positive = positive electrode solid-phase diffusion coefficient
  • eps_e_s = epsilon-electrolyte-separator = separator electrolyte volume fraction

1.4 SOC and N/P Ratio

  • Battery SOC ≠ electrode SOC; change in opposite directions during discharge
  • Lithium conservation constraint: N_total × ΔSOC_n = P_total × ΔSOC_p
  • N/P ratio = negative electrode total capacity / positive electrode total capacity
  • In parameters.py, only battery_soc_initial needs to be set; electrode SOC is computed automatically

1.5 OCV Curves

  • Nernst Equation: Thermodynamic equilibrium potential for ideal solutions

$$
OCV(\theta) = U_0 + \frac{RT}{F} \cdot \ln!\left(\frac{\theta}{1-\theta}\right)
$$

  • Graphite negative electrode: tanh function fits staircase-like plateaus (phase transition characteristics)
  • NMC positive electrode: quadratic polynomial fit, $OCV_{\mathrm{NMC}}(\theta) = 4.15 - 0.9\theta + 0.2\theta^2$
  • Cell open-circuit voltage: $V_{\mathrm{cell}} = OCV_p - OCV_n$

II. 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 governing equations) Complete (to be studied)
spm/__init__.py Package initialization Complete
visualize_ocv.py OCV visualization script Complete
requirements.txt numpy, scipy, matplotlib Complete

2.2 Functions Already Implemented in model.py

1
2
3
4
5
6
7
8
9
ocv_negative(theta)          # Graphite negative OCV (tanh fit)
ocv_positive(theta) # NMC positive OCV (quadratic polynomial)
ocv_negative_nernst(theta) # Pure Nernst for teaching
ocv_positive_nernst(theta) # Pure Nernst for teaching
_build_diffusion_matrix(...) # Tridiagonal matrix construction ← focus of this session
butler_volmer_overpotential(...) # BV inverse solution
SPMModel.__init__() # Initialize grid, concentration, specific surface area
SPMModel.step(i_app) # Single-step simulation (core) ← focus of this session
SPMModel.simulate(...) # Batch simulation

2.3 Key Parameters in parameters.py (used in this session)

Parameter Value Meaning Role in Diffusion
R_n, R_p 5 μm Particle radius Spatial domain [0, R]
D_s_n 3.9e-14 m²/s Negative electrode diffusivity Diffusion speed
D_s_p 1.0e-13 m²/s Positive electrode diffusivity Diffusion speed
c_s_max_n 31507 mol/m³ Negative max concentration SOC normalization reference
c_s_max_p 51554 mol/m³ Positive max concentration SOC normalization reference
Nr 50 Radial discretization points Spatial resolution
dt 1.0 s Time step Temporal resolution
T 298.15 K Temperature Affects diffusion coefficient

2.4 Figure Generation Notes

This course uses matplotlib to generate PNG figures (consistent with course 1 visualize_ocv.py style):

Session Image File Content
2.1 diffusion_concept.png Diffusion physical concept (concentration gradient, flux direction, spherical shell onion model)
2.2 diffusion_discretization.png Discretization illustration (node grid, tridiagonal matrix structure, boundary condition schematic)
2.3 diffusion_simulation.png Numerical simulation results (concentration profile evolution, different parameter comparisons)

III. Current Session Topic

Numerical Implementation of the Diffusion Equation (Fick’s Second Law)

Among SPM’s four governing equations, the diffusion equation describes how lithium atom concentration inside a spherical particle evolves over time. This is key to understanding battery polarization and concentration distribution.


IV. Three-Session Step-by-Step Learning Plan

Teaching positioning: Assumes zero mathematical background, starting from “what is concentration” and progressively deriving up to matrix operations.
Learning method: Each session includes hand-derivation exercises + PNG figure visualization.

1
2
3
4
Session 2.1 ────→ Session 2.2 ────→ Session 2.3
Physical Intuition Numerical Methods Code Practice
(Zero-basis intro) (Hand-derive) (Rewrite+Compare)
Shorter Longest Medium

Session 2.1: What is Diffusion? — From “a Cup of Sugar Water” to the Spherical Coordinate Equation

Goal: Build physical intuition, no code or matrices
Difficulty: ⭐ · Pure concepts

2.1.1 Learning Content

# Topic Core Question Teaching Method
1 What is concentration Starting from “sugar dissolving in water”: c = amount of substance ÷ volume, unit mol/m³. Lithium in particles is like sugar in water — some regions more concentrated, others more dilute. Everyday analogy
2 Fick’s First Law The driving force of diffusion is concentration gradient — “water flows downhill”. J = −D · ∂c/∂r, each symbol explained character by character: J is flux (moles per second per square meter), D is diffusion coefficient (how fast it moves), ∂c/∂r is concentration gradient (how steep the slope). The negative sign indicates flow from high to low concentration. Formula decomposition + illustration
3 Fick’s Second Law Derive from mass conservation — imagine a thin shell inside the particle, inflow J(r) from left, outflow J(r+dr) from right; net change = inflow − outflow, substitute J = −D·∂c/∂r to obtain ∂c/∂t = D·∂²c/∂r² (Cartesian form). Hand-derive: 1D mass conservation → PDE
4 Why spherical coordinates Battery particles are spherical! Shell volume ∝ r², outer layers can hold more lithium than inner layers. For shells of equal thickness: near-center shell volume is small → small amount of Li changes concentration dramatically; near-surface shell volume is large → needs more Li. This introduces the 1/r² factor in the equation. Onion model + diagram
5 Spherical equation expansion ∂c/∂t = D · [∂²c/∂r² + (2/r) · ∂c/∂r]. Physical meaning of each term: ∂²c/∂r² is the “curvature effect” (also present in Cartesian), (2/r)·∂c/∂r is the “geometric focusing effect” (unique to spherical coordinates). Term-by-term explanation
6 Two boundary conditions Center (r=0): Symmetry → concentration profile is “flat” at center (∂c/∂r=0). The center is a perfect symmetry point, lithium diffuses uniformly from all directions, net flux is zero. Surface (r=R): Flux determined by current (D·∂c/∂r = j). During discharge j<0 (deintercalation), concentration is lowest at surface. Diagram + physical intuition
7 Analogy understanding Particle = circular sponge absorbing/squeezing water. Discharge = squeezing water out from surface, squeeze too fast → surface dries out → this is the root of “concentration polarization”. If diffusion is fast enough (large D), internal water continuously replenishes the surface. If diffusion is too slow (small D), surface is dry but interior is still wet. Analogy

2.1.2 Hand-Derivation Exercise

Derive Fick’s Second Law (Cartesian form) starting from 1D mass conservation:

1
2
3
4
5
6
7
8
9
10
11
12
Step 1: Write mass conservation
Rate of concentration change × volume = inflow − outflow
(∂c/∂t) · (A·dr) = J(r)·A − J(r+dr)·A

Step 2: Divide both sides by volume A·dr
∂c/∂t = [J(r) − J(r+dr)] / dr = −∂J/∂r

Step 3: Substitute Fick's First Law J = −D·∂c/∂r
∂c/∂t = −∂(−D·∂c/∂r)/∂r = D·∂²c/∂r²

Step 4: Extend to spherical coordinates (accept the result, derivation is complex)
∂c/∂t = D·(1/r²)·∂(r²·∂c/∂r)/∂r = D·[∂²c/∂r² + (2/r)·∂c/∂r]

2.1.3 Generate Figure: diffusion_concept.png

Use matplotlib to generate PNG, style referencing visualize_ocv.py

Subplot 1: 1D diffusion illustration

  • X-axis: position r, Y-axis: concentration c
  • Draw a descending curve from left to right (high concentration → low concentration)
  • Label concentration gradient ∂c/∂r (slope), arrow from high to low concentration labeled J (diffusion flux direction)
  • Annotation text: “J = −D · ∂c/∂r”, “Diffusion direction: high C → low C”

Subplot 2: Spherical “onion model”

  • Draw a circle (particle cross-section), draw 3-4 concentric rings (spherical shells) inside
  • Label r=0 (center), r=R (surface)
  • Annotate each shell with different volume hints (inner shell small, outer shell large)
  • Title: “Shell volume ∝ r², larger near surface”

Subplot 3: Expected concentration distribution during discharge

  • Draw a circle, use color (or grayscale) to indicate concentration: light at surface (low concentration), dark interior (high concentration)
  • Label arrows: surface → exterior (deintercalation direction), interior → surface (diffusion replenishment direction)
  • Title: “Negative electrode particle during discharge: surface deintercalation → interior diffusion replenishment”

2.1.4 Extended Thinking (preview for 2.2)

  1. If we want to solve the spherical diffusion equation on a computer, how many segments should we slice the continuous r into?
  2. How does a computer compute “∂c/∂r”? Computers only do addition, subtraction, multiplication, and division — they can’t take derivatives.

Session 2.2: Turning Equations into Matrices — Finite Differences and Implicit Euler

Goal: Hand-derive all discretization formulas, understand the origin of every matrix coefficient
Difficulty: ⭐⭐⭐ · Mathematical core, “hard bone”

2.2.1 Learning Content

# Topic Core Question Teaching Method
1 Why numerical solutions PDEs have no general analytical solution. The spherical diffusion equation (with time-varying boundary conditions) can only be solved numerically. Motivation
2 Spatial discretization basics Place Nr=50 points uniformly on [0, R]. Spacing dr = R/(Nr−1). Node i=0 is center, i=Nr−1 is surface. Convert continuous c(r,t) to discrete array c[0], c[1], …, c[Nr−1]. Diagram + example
3 Finite difference introduction Derive difference formulas from Taylor expansion: f(x+h) = f(x) + h·f’(x) + (h²/2)·f’’(x) + … . 1st-order central difference: (c_{i+1}−c_{i-1})/(2dr). 2nd-order: (c_{i+1}−2c_i+c_{i-1})/dr². Hand-derive Taylor expansion. Hand-derive Taylor → differences
4 Spherical Laplacian discretization ⭐⭐ The most critical step. Substitute difference formulas into ∇²c = ∂²c/∂r² + (2/r)·∂c/∂r, combine like terms to obtain α_i, β_i, γ_i. Hand-derive the combination process. Hand-derive core derivation
5 Explicit vs. Implicit Euler Explicit: c_new = c_old + Δt·D·∇²c_old → simple but Δt < dr²/(2D) ≈ 0.13s (for negative electrode D=3.9e-14, dr≈0.1μm). Implicit: c_new − Δt·D·∇²c_new = c_old → requires solving linear system, but Δt can be arbitrarily large (unconditionally stable). Calculate CFL condition with actual parameters. Example calculation + comparison
6 Tridiagonal matrix assembly Implicit Euler in matrix form: (I − Δt·D·L)·c_new = c_old. L is the discrete Laplacian tridiagonal matrix. Draw the sparse pattern (only three lines). Diagram: matrix structure
7 Center boundary (i=0) At r=0, 1/r → ∞, discrete formula fails. Use L’Hôpital’s rule: lim_{r→0} (2/r)·∂c/∂r = 2·∂²c/∂r². Substituting yields ∇²c₀ = 6(c₁−c₀)/dr². Why 6 and not 4? Hand-derive. Hand-derive L’Hôpital
8 Surface Neumann boundary (i=Nr−1) D·(c_{Nr−1} − c_{Nr−2})/dr = j. Here j comes from the electrochemical reaction (Butler-Volmer), a known quantity. During discharge j<0 → c_surf < c_near (surface concentration lower). Physical meaning
9 scipy banded storage solve_banded((1,1), ab, rhs). Why (1,1)? Lower bandwidth=1, upper bandwidth=1. What do the 3 rows of ab store? ab[0]=upper diagonal, ab[1]=main diagonal, ab[2]=lower diagonal. Code interface

2.2.2 Core Hand-Derivation: Spherical Laplacian Discretization

This is the most important derivation of the entire second course. Recommended to work through on paper step by step:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Given:
∇²c = ∂²c/∂r² + (2/r)·∂c/∂r

Finite difference approximations:
∂²c/∂r²|_i ≈ (c_{i+1} − 2c_i + c_{i-1}) / dr²
∂c/∂r|_i ≈ (c_{i+1} − c_{i-1}) / (2·dr)

Substitute and combine like terms:
∇²c_i = (c_{i+1}−2c_i+c_{i-1})/dr² + (2/r_i)·(c_{i+1}−c_{i-1})/(2dr)
= (c_{i+1}−2c_i+c_{i-1})/dr² + (c_{i+1}−c_{i-1})/(r_i·dr)
= (1/dr²)·c_{i-1} + (−2/dr²)·c_i + (1/dr²)·c_{i+1}
+ [1/(r_i·dr)]·c_{i+1} − [1/(r_i·dr)]·c_{i-1}

c_{i-1} coefficient: 1/dr² − 1/(r_i·dr) = (1 − dr/r_i)/dr² = α_i
c_i coefficient: −2/dr² = β_i
c_{i+1} coefficient: 1/dr² + 1/(r_i·dr) = (1 + dr/r_i)/dr² = γ_i

Final result:
∇²c_i = α_i·c_{i-1} + β_i·c_i + γ_i·c_{i+1}
α_i = (1 − dr/r_i) / dr²
β_i = −2 / dr²
γ_i = (1 + dr/r_i) / dr²

After completing the derivation, open model.py and compare alpha and gamma in _build_diffusion_matrix — verify that the code matches your derivation exactly.

2.2.3 Hand-Derivation: Center Boundary (i=0)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
As r → 0:
(2/r)·∂c/∂r → 0/0 indeterminate form
Apply L'Hôpital's rule:
lim_{r→0} (2·∂c/∂r) / r = 2·∂²c/∂r²|_{r=0}

Therefore at center:
∇²c|₀ = ∂²c/∂r² + 2·∂²c/∂r² = 3·∂²c/∂r²|_{r=0}

Express ∂²c/∂r²|₀ using finite differences:
Symmetry → c_{-1} = c_1 (ghost node)
∂²c/∂r²|₀ = (c₁ − 2c₀ + c_{-1}) / dr² = 2(c₁ − c₀) / dr²

Final:
∇²c|₀ = 3 × 2(c₁ − c₀)/dr² = 6(c₁ − c₀) / dr²

2.2.4 Explicit vs. Implicit: Calculate with Actual Parameters

1
2
3
4
5
6
7
8
9
10
Parameters: D = 3.9e-14 m²/s, R = 5e-6 m, Nr = 50
dr = 5e-6 / 49 ≈ 1.02e-7 m

Explicit Euler CFL condition:
Δt < dr² / (2D) = (1.02e-7)² / (2 × 3.9e-14)
= 1.04e-14 / 7.8e-14
≈ 0.13 s

This means simulating 1 hour of discharge requires ~28,000 steps with explicit!
Implicit Euler with Δt=1s needs only 3,600 steps → ~8× faster.

2.2.5 Generate Figure: diffusion_discretization.png

Subplot 1: Particle discrete grid

  • Draw a circle (particle cross-section), mark node positions along a radius
  • Nodes 0 (center), 1, 2, …, Nr−1 (surface), marked with dots
  • Label dr spacing
  • Title: “N=50 nodes, dr = R/(N−1)”

Subplot 2: Tridiagonal matrix structure (spy plot)

  • Use plt.spy() or manually draw non-zero element pattern
  • Show only three diagonals (upper, main, lower)
  • Color-code: main diagonal (blue), upper diagonal (red), lower diagonal (green)
  • Label row indices and corresponding node i
  • Title: “Banded matrix structure: only adjacent nodes are coupled”

Subplot 3: Boundary condition illustration

  • Left: center symmetry condition — c_{-1}=c_1 (ghost mirror), label ∂c/∂r=0
  • Right: surface flux condition — D·(c_{Nr−1}−c_{Nr−2})/dr = j, arrow indicating j direction

2.2.6 Extended Thinking (preview for 2.3)

  1. What does the parameter (1,1) passed to scipy.linalg.solve_banded mean?
  2. Why is the surface Neumann boundary placed in the RHS (right-hand side vector) rather than in the matrix?

Session 2.3: Writing Code from Scratch — Rewrite, Compare, Run

Goal: Implement the diffusion solver independently without referencing the original code, then compare and learn
Difficulty: ⭐⭐ · Hands-on practice

2.3.1 Learning Content

# Topic Core Question Teaching Method
1 Understanding scipy interface Detailed explanation of solve_banded((l,u), ab, rhs) parameters. l=1 (lower bandwidth), u=1 (upper bandwidth), ab is (l+u+1, N) matrix, column-major storage. Documentation walkthrough
2 Write build_diffusion_matrix(N, D, dt, dr, r_nodes) from scratch No reference! Based on Session 2.2 derivations, assemble the tridiagonal matrix yourself. Handle three regions: i=0 (center boundary), i=1..N−2 (interior nodes), i=N−1 (surface). Independent coding
3 Write a minimal diffusion solver from scratch Manually set parameters (R=5μm, D=4e-14, Nr=50, dt=1s, j=−1e-6), initialize uniform concentration c_init = 0.5·c_max, loop time steps solving, update surface boundary RHS each step. Independent coding
4 Comparison analysis Your implementation vs. model.py original. Key differences: original places surface BC in RHS rather than matrix — why? Which design is clearer? What is the cost of decoupling? Code style differences? Code comparison
5 Parameter experiments D increased 10× → concentration more uniform (flatter profile); j increased → surface concentration drops faster; Δt changed from 1s to 10s → verify implicit Euler stability; Nr changed from 50 to 20 and 100 → accuracy vs. speed trade-off. Experiment + plot
6 Trace step() flow Complete walkthrough of step() Step 3 (diffusion part) in model.py: surface flux j → RHS construction → solve_banded → obtain new concentration array. Code walkthrough

2.3.2 Independent Coding Checklist

Create file learning/learning_notes_02_diffusion/diffusion_solver_my.py (purely educational, independent of SPM), containing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Function signatures to implement from scratch:

build_diffusion_matrix(N, D, dt, dr, r_nodes) → (3, N) banded matrix
- Build spherical-coordinate implicit Euler diffusion matrix
- Center (i=0): ∂c/∂r=0 → 6(c₁−c₀)/dr²
- Interior (i=1..N-2): αᵢc_{i-1} + βᵢc_i + γᵢc_{i+1}
- Surface (i=N-1): Neumann BC (handled via RHS at solve time)
- Uses banded storage format for scipy.solve_banded

solve_one_step(c_old, ab, j, D, dr) → c_new
- Execute one implicit Euler step: solve (I − DΔt·L)·c_new = c_old
- j: surface flux [mol/(m²·s)], positive=intercalation, negative=deintercalation
- Surface Neumann BC injected via RHS modification

simulate_diffusion(R, D, c_max, soc_init, Nr, dt, n_steps, j) → (c_history, time)
- Run pure diffusion simulation (no electrochemical coupling)
- Pre-build matrix once, reuse with RHS updates each step
- Returns: c_history[n_steps, Nr] — concentration evolution over time

Then write learning/learning_notes_02_diffusion/plot_diffusion_results.py for visualization.

2.3.3 Comparison Analysis Checklist

After completing independent coding, open spm/model.py and compare the following:

Comparison Point Your Implementation model.py Original Difference Analysis
Surface BC placement ? RHS (not in matrix) Original pre-builds matrix in init (without surface BC), step modifies RHS last entry each time
Matrix storage format ? (3, Nr) solve_banded Are they consistent?
Diffusion-Chemistry decoupling ? Fully independent Diffusion only cares about j value, not where j comes from
Code commenting style ? Physical meaning + derivation chain Any differences?
Naming convention ? lam, alpha, gamma Are they consistent?

2.3.4 Generate Figure: diffusion_simulation.png

Subplot 1: Concentration profile evolution

  • X-axis: r (μm), Y-axis: c / c_max (normalized concentration, i.e., SOC)
  • Draw multiple curves, each representing different times (t=0, 60s, 300s, 1200s, 3600s)
  • Discharge process: surface SOC gradually decreases, interior remains higher
  • Labels: surface SOC (lowest point), center SOC (highest point), concentration gradient

Subplot 2: Diffusion coefficient sensitivity

  • At the same time point (e.g., t=600s), draw three concentration profiles for different D values
  • D=3.9e-14 (baseline), D×5, D×10
  • Demonstrate that larger D gives more uniform concentration, smaller D causes deeper surface drop

Subplot 3: Center vs. surface SOC time evolution

  • X-axis: time t (s), Y-axis: SOC
  • Two curves: c_surf/c_max (surface), c_center/c_max (center)
  • Gap between the two curves = degree of concentration polarization
  • Label maximum gap point

2.3.5 Your Implementation vs. Original File Structure

1
2
3
4
5
6
7
8
9
learning/learning_notes_02_diffusion/
├── session_02_background.md # This file
├── learning_notes_02_diffusion.md # Study notes (generated after three sessions)
├── diffusion_solver_my.py # [Your independent implementation] diffusion solver from scratch
├── plot_diffusion_results.py # Visualization script (your implementation)
├── diffusion_concept.png # Session 2.1 output
├── diffusion_discretization.png # Session 2.2 output
├── diffusion_simulation.png # Session 2.3 output (your implementation)
└── diffusion_simulation_ref.png # Session 2.3 output (original model.py result, for comparison)

diffusion_simulation_ref.png is generated by directly calling spm/model.py‘s SPMModel with the same diffusion scenario, used for visual comparison with your implementation.


V. Preview Questions (Across All Three Sessions)

# Question Related Session
1 Why does sugar eventually distribute uniformly in a cup of water left undisturbed? What drives the sugar molecules? 2.1
2 In spherical coordinates, why does the diffusion equation gain the (2/r)·∂c/∂r term? What would happen without it? 2.1
3 Why choose Implicit Euler over Explicit Euler? Calculate the maximum explicit time step using actual negative electrode parameters. 2.2
4 Why does ∂c/∂r|_{r=0}=0 require modifying the Laplacian discretization? What would happen using the interior node formula directly? 2.2
5 What advantage does banded storage provide for tridiagonal matrices? How many zeros are stored in a full 50×50 matrix? 2.2
6 During discharge, why is the negative electrode surface concentration lower than the interior? What happens if diffusion coefficient D approaches infinity? 2.1+2.3
7 If the surface flux j varies with time (e.g., pulse discharge), where does your code need to change? 2.3

VI. Connection to Next Chapter

After completing the diffusion equation study, the next chapter will cover Butler-Volmer Kinetics (Session 3):

$$
j = j_0 \cdot \left[ \exp!\left(\frac{\alpha F \eta}{RT}\right) - \exp!\left(-\frac{(1-\alpha)F \eta}{RT}\right) \right]
$$

where $j_0 = k \cdot c_e^{1-\alpha} \cdot c_s^{\alpha} \cdot (c_{\mathrm{max}} - c_s)^{1-\alpha}$

Relationship chain between the two chapters:

1
2
3
4
5
Diffusion Equation (Ch 2)              BV Kinetics (Ch 3)
↓ ↓
Provides surface c_s_surf ──→ Computes overpotential η
↓ ↓
└──────────→ Voltage coupling V_cell ←──────────┘

Diffusion answers “how is lithium distributed inside the particle”, BV answers “how difficult is the surface reaction”. Together they determine the cell terminal voltage.


VII. Technical Details Memo (for AI assistant reference)

7.1 Figure Generation Standards

  • Use matplotlib, Chinese labels use Microsoft YaHei font
  • plt.savefig(filename, dpi=150, bbox_inches='tight')
  • Place in learning/learning_notes_02_diffusion/ directory
  • At least one figure per session, use plt.subplots for multi-panel layout

7.2 Formula Standards

  • Follow note_specification.md, use KaTeX-compatible syntax
  • No Chinese inside formulas, use \mathrm{English} instead of \text{}
  • Annotate complex formulas with parameter description tables (symbol, name, unit)

7.3 Teaching Principles

  • Zero basis: Every new concept starts with an everyday analogy before entering formulas
  • Hand-derivation verification: Key derivations require the student to write them out, then verify against code
  • Diagrams over text: Use PNG figures wherever possible, no ASCII art
  • Comparative learning: Independent implementation → compare with original → understand design philosophy behind differences

VIII. Reference File Index

Path Description
../learning_notes_01_foundation/learning_notes_01_foundation.md Course 1 complete notes (OCV + SPM fundamentals)
../../spm/model.py SPM core code (_build_diffusion_matrix, step())
../../spm/parameters.py Battery parameters (R_n, D_s_n, Nr, dt, etc.)
../../visualize_ocv.py Course 1 figure generation code (style reference)
../../note_specification.md Note writing standards (formulas, formatting)

Session background file · Version 2.0
Created: 2026-05-22 · Updated: 2026-05-25
Next session: Say “Please read session_02_background.md to begin Session 2.1” in the conversation

0%