Skip to content

Repository files navigation

CarrierCapture.py

Tests Python Version License: MIT Code style: black

Modern Python package for computing carrier capture rates and non-radiative recombination in semiconductors using multiphonon theory.

CarrierCapture.py started life as an automated rewrite of CarrierCapture.jl with emphasis on clean code, performance, and interactive visualization.


✨ Features

🧮 Complete Multiphonon Theory Implementation

  • 1D Schrödinger equation solver (ARPACK-based)
  • Harmonic, Morse, and spline potential fitting
  • Configuration coordinate diagrams
  • Capture coefficient calculations

⚡ High-Performance Computing

  • Parallel parameter scanning with joblib
  • Optimized with NumPy/SciPy (within 10-20% of Julia speed)
  • Support for HDF5 and NPZ result storage

🎨 Rich Visualization

  • Publication-quality plots with Plotly
  • Interactive Dash dashboard (web-based)
  • Real-time parameter exploration
  • Arrhenius plots, CC diagrams, 2D heatmaps

🔧 Command-Line Interface

  • Click-based CLI with intuitive subcommands
  • YAML configuration files
  • Progress bars and rich terminal output
  • DFT preprocessing utilities

🔗 Integration with doped

  • Direct compatibility with doped defect calculation workflows
  • Load configuration coordinate data from doped outputs
  • Automated mass-weighted displacement calculations
  • Seamless end-to-end: DFT → defect analysis → capture rates

🔬 Scientific Validation

  • Validated against CarrierCapture.jl
  • Comprehensive test suite (169 tests)
  • Tutorial notebooks with real examples

📦 Installation

From PyPI (coming soon)

pip install carriercapture

From Source

git clone https://github.com/WMD-group/CarrierCapture.py.git
cd CarrierCapture.py
pip install -e ".[dev]"

Optional Dependencies

# doped integration (for defect calculations)
pip install carriercapture[doped]

# Jupyter notebook support
pip install carriercapture[notebook]

# Development tools (tests, linting)
pip install -e ".[dev]"

🚀 Quick Start

Python API

import numpy as np
from carriercapture.core.potential import Potential
from carriercapture.core.config_coord import ConfigCoordinate

# Create harmonic potentials
pot_initial = Potential.from_harmonic(hw=0.008, Q0=0.0, E0=0.5)
pot_final = Potential.from_harmonic(hw=0.008, Q0=10.5, E0=0.0)

# Solve Schrödinger equation
pot_initial.solve(nev=180)
pot_final.solve(nev=60)

# Calculate capture coefficient
cc = ConfigCoordinate(pot_i=pot_initial, pot_f=pot_final, W=0.068)
cc.calculate_overlap(Q0=5.0)
cc.calculate_capture_coefficient(
    volume=1e-21,
    temperature=np.linspace(100, 500, 50)
)

print(f"Capture coefficient at 300K: {cc.capture_coefficient[20]:.3e} cm³/s")

Command-Line Interface

# Fit potential from DFT data
carriercapture fit data/excited.dat -f spline -o 4 -s 0.001 -O excited.json

# Solve Schrödinger equation
carriercapture solve excited.json -n 180 -O excited_solved.json

# Calculate capture coefficient
carriercapture capture config.yaml -V 1e-21 --temp-range 100 500 50

# High-throughput parameter scan
carriercapture scan --dQ-min 0 --dQ-max 25 --dQ-points 25 -W 0.05 \
                    --dE-min 0 --dE-max 2.5 --dE-points 10 \
                    -j -1 -o scan_results.npz

# Launch interactive dashboard
carriercapture viz --port 8050

Integration with doped

See the doped NEB / CC diagram tutorial, for ensuring appropriately oriented and ordered structures for configuration-coordinate diagram (and NEB path) generation, to ensure appropriate structure interpolation.

# Load defect data from doped workflow
from carriercapture.io.doped_interface import (
    load_defect_entry,
    create_potential_from_doped
)

# Load defect entry from doped calculation
defect = load_defect_entry("path/to/defect.json.gz")

# Create potentials for charge state transition (0 → +1)
pot_initial = create_potential_from_doped(defect, charge_state=0)
pot_final = create_potential_from_doped(defect, charge_state=+1)

# Continue with standard CarrierCapture workflow
pot_initial.solve(nev=180)
pot_final.solve(nev=60)
# ... calculate capture coefficient

📚 Documentation

Tutorial Notebooks

Full examples in examples/ directory with detailed README.

CLI Reference

carriercapture --help

Available commands:

Command Description
fit Fit potential energy surface
solve Solve Schrödinger equation
capture Calculate capture coefficient
scan High-throughput parameter scanning
scan-plot Visualize scan results
viz Launch interactive dashboard
plot Generate static plots

🔬 Scientific Background

CarrierCapture implements the static coupling approximation for non-radiative carrier capture via multiphonon emission (Huang-Rhys theory).

Key Equations

Capture coefficient:

$$C(T) = \frac{V \cdot 2\pi}{\hbar} \cdot g \cdot W^2 \cdot \sum_{i,j} p_i |\langle\chi_i|Q-Q_0|\chi_j\rangle|^2 \delta(\varepsilon_i - \varepsilon_j)$$

Where:

  • V: supercell volume
  • g: degeneracy factor
  • W: electron-phonon coupling matrix element (eV/(amu^0.5·Å))
  • pᵢ: thermal occupation of initial state i
  • χᵢ, χⱼ: vibrational wavefunctions
  • δ: energy-conserving delta function (Gaussian broadened)

References

  1. Alkauskas et al. (2014) - First-principles calculations of luminescence spectrum line shapes for defects in semiconductors, Phys. Rev. B 90, 075202
  2. Huang & Rhys (1950) - Theory of Light Absorption and Non-Radiative Transitions in F-Centres, Proc. R. Soc. Lond. A 204, 406

🧪 Testing

# Run all tests
pytest tests/ -v --cov

# Run specific test modules
pytest tests/test_parameter_scan.py -v
pytest tests/test_visualization.py -v

# Run with coverage report
pytest tests/ --cov=src/carriercapture --cov-report=html

Test Statistics:

  • 169 tests (doped-integration tests skip without the optional doped package)
  • Core modules: >90% coverage
  • Supported Python versions: 3.9-3.12
  • CI/CD with GitHub Actions

🏎️ Performance

Benchmarked against CarrierCapture.jl on typical workflows:

Operation Python Julia Ratio
Schrödinger solver (N=5000) 0.42 s 0.38 s 1.11×
Capture coefficient 0.15 s 0.13 s 1.15×
Parameter scan (25×10) 45 s 38 s 1.18×

Python within 20% of Julia due to shared ARPACK/FITPACK backends.


🔬 Validation Against Julia

CarrierCapture.py has been validated against the original CarrierCapture.jl implementation to ensure numerical accuracy.

Benchmark: Sn_Zn in ZnO

Test Case: Harmonic potential approximation for Sn substituting Zn in ZnO

Parameters:

  • Phonon energy: ℏω = 8 meV
  • Configuration coordinate shift: ΔQ = 10.5 amu^0.5·Å
  • Energy offset: ΔE = 0.5 eV
  • Electron-phonon coupling: W = 0.068 eV/(amu^0.5·Å)

Results (three-tier comparison):

Tier Comparison Max Relative Diff Status
1 Julia-convention emulation vs Julia reference (eigenvalues) 3×10⁻¹² ✓ PASS
1 Julia-convention emulation vs Julia reference (C at 300 K) 5×10⁻¹² ✓ PASS
2 Native eigenvalues vs analytic ℏω(n+½) 1.5×10⁻⁴ ✓ PASS
3 Native C(300 K) = 1.339×10⁻¹⁰ vs Julia 1.359×10⁻¹⁰ cm³/s 1.5×10⁻² ✓ (informational)

Conclusion: When Python is run with CarrierCapture.jl's numerical conventions, the two codes agree to near machine precision (Tier 1) — they implement identical physics. The ~1.5% native difference (Tier 3) is entirely due to two CarrierCapture.jl conventions: its finite-difference kinetic term uses grid spacing ΔQ/N while its grid actually has spacing ΔQ/(N−1), and it integrates overlaps with the rectangle rule. Python uses the true grid spacing and the trapezoid rule, and its native eigenvalues are closer to the analytic harmonic result (Tier 2). Both codes converge to the same answer with increasing grid density.

Running the Benchmark

Requirements:

  • Julia with CarrierCapture.jl installed
  • Python with CarrierCapture.py installed
# Run full benchmark (from repository root)
./benchmarks/run_benchmark.sh

# Or run manually
julia benchmarks/run_julia_reference.jl
python benchmarks/benchmark_sn_zn.py

Results are saved to benchmarks/results/benchmark_report.json.

See benchmarks/README.md for details.


🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Development Setup

git clone https://github.com/WMD-group/CarrierCapture.py.git
cd CarrierCapture.py
pip install -e ".[dev]"
pytest tests/  # Run tests

Code Style

This project uses:

  • black for code formatting
  • ruff for linting
  • Type hints throughout

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.


🙏 Acknowledgments

  • Original Julia implementation: WMD-group/CarrierCapture.jl
  • Built with: NumPy, SciPy, Plotly, Dash, Click
  • Compatible with: doped (defect calculations)
  • Developed with assistance from Claude (Anthropic)

📧 Contact & Support


📊 Project Status

Component Status
Core Engine ✅ Complete
CLI ✅ Complete
Visualization ✅ Complete
Parameter Scanning ✅ Complete
doped Integration ✅ Complete
Documentation ✅ Complete
Test Coverage ✅ 169 tests
PyPI Release 🔄 Planned

⭐ Star this repo if you find it useful! ⭐

About

Python package to compute trap-assisted electron and hole capture in semiconductors

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages