Toolkit to simulate and visualize hole spin transport properties in quasi-1D wires (Datta–Das SFET based), including time evolution, T(E)/R(E), spin precession, and device-level metrics + reports.
# build + install the package
make build
pip install --force-reinstall --no-deps packages/spintransport/dist/*.whlRequirements
- Python ≥ 3.10
numpy,scipy,matplotlib,torch- For MP4 export: ffmpeg in your PATH (
sudo apt install ffmpegon Ubuntu)
For development work, install the package in editable mode:
# Install in development mode
pip install -e packages/spintransport/This allows you to make changes to the code and see the effects immediately without reinstalling.
# 1) run a simulation (example values!)
spintransport-sim \
--L_A 1200 --T_fs 108.9 --dy_A 1.0 --dt_fs 0.968 \
--E_min 0.0 --E_max 1.5 --nE 101 \
--gamma1 6.790 --gamma2 1.900 --gamma3 2.681 \
--Lb_A 20 --Vb_eV 0.3 --beta_eff_eVA 0.4 \
--out rashba_out
# 2) interactive time evolution (slider)
spintransport-time-evolution --dir rashba_out --layout split
# 3) export video
spintransport-export-mp4 --dir rashba_out --layout split --energy-index 50
spintransport-export-gif --dir rashba_out --layout shared
# 4) plot T(E), R(E)
spintransport-plot-tr --dir rashba_out --mode TR
# 5) spin precession in a region
spintransport-plot-precession --dir rashba_out --pair hh --region right --mode abs
# 6) device metrics & summaries
spintransport-export-report --dir rashba_out
spintransport-export-summary --dir rashba_outEnergy index? It’s the discrete index i = 0..nE-1 of the energy grid you requested:
\[
E_i = E_{\min} + i\,\frac{E_{\max}-E_{\min}}{nE-1}.
\]
i=0 → Emin, i=nE-1 → Emax, mid → nE//2.
Inside --out (e.g., rashba_out/):
psi.npy— complex array(4*ny, nt, nE)with components[HH↑, LH↑, LH↓, HH↓].E_eV.npy— energy axis (eV).T.npy,R.npy— (auto-computed on demand) arrays(4, nE)per component.Ttot.npy,Rtot.npy— totals(nE).meta.json— grid + barrier + Rashba parameters (ny, nt, dy_Å, dt_fs, yL, yR, Lb_Å, Vb_eV, beta_eff_eVA, …).- Optional exports:
evolution_*.mp4,evolution_*.gif,snapshot_*.png,metrics_report.json,summary.md.
Programmatic load:
from spintransport.io.simio import read_sim
sim = read_sim("rashba_out")
# sim.psi, sim.ny, sim.nt, sim.nE, sim.dy_A, sim.dt_fs, sim.yL, sim.yR, sim.meta, sim.energies_eVRun the simulator and write results.
spintransport-sim \
--L_A <Å> --T_fs <fs> --dy_A <Å> --dt_fs <fs> \
--E_min <eV> --E_max <eV> --nE <int> \
--gamma1 <float> --gamma2 <float> --gamma3 <float> \
--Lb_A <Å> --Vb_eV <eV> --beta_eff_eVA <eV·Å> \
--out <folder>What it does: builds the total Hamiltonian (Kohn–Luttinger + Rashba + V), evolves a 4-component wavepacket for each energy in the grid, and writes psi.npy, E_eV.npy, meta.json to --out.
Interactive viewer with a time slider (+ optional PNG snapshots).
spintransport-time-evolution --dir <results_dir> [--energy-index <i>] \
[--layout shared|split] [--style <mpl-style>] [--no-mmap] \
[--snap <t>]... [--snap-outdir <dir>] [--png-dpi <int>]layout shared: HH & LH on the same positive axis.layout split: HH positive, LH negative (mirror) to separate visually.--snap t: save a PNG snapshot for time indext(repeatable).
What it does: visualizes |ψ|²(y,t;E) by component, with optional snapshot export.
Export the time evolution to MP4 (requires ffmpeg).
spintransport-export-mp4 --dir <results_dir> [--energy-index <i>] \
[--layout shared|split] [--fps <int>] [--stride <int>] \
[--dpi <int>] [--style <mpl-style>] [--outfile <path>] \
[--codec libx264] [--bitrate <kbps>] [--no-mmap]What it does: renders an MP4 animation of |ψ|²(y,t;E). When layout split, LH curves are the negative mirror.
Same as MP4, but outputs an animated GIF (no ffmpeg needed).
spintransport-export-gif --dir <results_dir> [--energy-index <i>] \
[--layout shared|split] [--fps <int>] [--stride <int>] \
[--dpi <int>] [--style <mpl-style>] [--outfile <path>] [--no-mmap]Plot T(E) and/or R(E) per component (no totals).
spintransport-plot-tr --dir <results_dir> [--mode T|R|TR] [--eindex-range I0 I1]mode T→ only T(E)mode R→ only R(E)mode TR→ T(E) (solid) and R(E) (dashed) overlayed--eindex-range I0 I1→ restrict to[I0..I1](inclusive) by energy index.
What it does: loads existing T.npy/R.npy if present, otherwise computes them from psi.npy and saves them.
Spin precession 〈σx〉, 〈σy〉, 〈σz〉 versus time in a region.
spintransport-plot-precession --dir <results_dir> \
[--pair hh|lh] [--region left|barrier|right|full] \
[--mode abs|cond] [--energy mid|avg|<i>|<i0>:<i1>] \
[--no-mark] [--style <mpl-style>] [--save <png>]- Modes:
abs: ⟨σ⟩ = ∫ ψ†σψ / ‖ψ(0)‖² → stays ~0 until wave arrives.cond: ⟨σ⟩ = ∫ ψ†σψ / ∫|ψ|² → local orientation (NaN before arrival).
- Arrival mark: automatic via occupancy gate (disable with
--no-mark).
What it does: computes precession from psi.npy in the chosen region (e.g., right lead) and plots time-series.
Export device metrics as JSON.
spintransport-export-report --dir <results_dir> \
[--Ef <eV>] [--T <K>] [--spin-deg] [--out <json>]What it does: writes <dir>/metrics_report.json with:
- T/R roll-ups over totals
Ttot(E)andRtot(E)(mean, std, max, on/off ratio). - Landauer conductance at (Ef, T) in e²/h, S, μS (use
--spin-degfor 2e²/h). - Spin precession summary in the right region (arrival time, final in-plane angle & amplitude).
Export a concise Markdown summary for design docs.
spintransport-export-summary --dir <results_dir> \
[--Ef <eV>] [--T <K>] [--spin-deg] [--out <md>]What it does: writes <dir>/summary.md with:
- Grid and barrier parameters (from
meta.json) - Highlights for transport (Ttot stats, on/off)
- Conductance at (Ef, T)
- Spin precession (region/pair/mode, arrival, final angle/amplitude)
- FFmpeg missing for MP4:
RuntimeError: ffmpeg writer not available→sudo apt install ffmpeg. - Memory: for large
(ny, nt, nE), prefer memmap (--no-mmapnot set) so viewers stream from disk. - X-axis: if
E_eV.npyis present and matchesnE, plots use eV. Otherwise the energy index is used. - Layouts:
shared→ all components positive.split→ LH components are the negative mirror (visual separation).
spintransport/
├─ cli/ # simulation runner
│ ├─ sim.py # main simulation with full KL + Rashba
│ └─ sim_nomix.py # simplified simulation without HH-LH mixing
├─ io/ # I/O helpers (read_sim, etc.)
├─ physics/ # numerical kernels and physics
│ ├─ st.py # core physics utilities and constants
│ ├─ wavepackets.py # initial wavepacket construction
│ └─ hamiltonian/ # modular Hamiltonian components
│ ├─ operators.py # common operators for all Hamiltonians
│ ├─ kohn_luttinger.py # Kohn-Luttinger Hamiltonian
│ └─ rashba.py # Rashba spin-orbit coupling
├─ analysis/ # data analysis modules
│ ├─ transmission.py # transmission and reflection calculations
│ ├─ tr_curves.py # T/R curve analysis
│ ├─ metrics.py # performance metrics
│ └─ precession.py # spin precession analysis
├─ viz/ # plotting & animation CLIs
└─ reports/ # JSON and Markdown exporters
The code includes several optimizations to improve performance:
-
Sparse matrix operations: Many operators in
physics/hamiltonian/operators.pyhave sparse variants (likeKY_sparse,KY2_sparse) that usescipy.sparseto efficiently handle large matrices with mostly zero elements. -
Modular Hamiltonian structure: The Hamiltonian components are modularized into separate files, allowing for easy customization and selective use (e.g., with or without HH-LH mixing using the
with_mixingparameter). -
Memory-efficient computation: For large simulations, streaming data from disk using memory mapping is supported via the
--no-mmapflag in visualization tools. -
Type safety: All functions are properly typed and ensure correct return types, especially for sparse matrix operations.
For developers extending this package, all modular components can be imported individually as needed:
# Import specific Hamiltonian components
from spintransport.physics.hamiltonian.operators import KY, KY2, KY_sparse, KY2_sparse, barrier_mask, potential_matrix
from spintransport.physics.hamiltonian.kohn_luttinger import kohn_luttinger_hamiltonian
from spintransport.physics.hamiltonian.rashba import rashba_hamiltonian
# Initial wavepacket construction
from spintransport.physics.wavepackets import initial_wavepacket_bandmix
# Transmission and reflection calculation
from spintransport.analysis.transmission import transmission_reflection
# Create a Hamiltonian with mixing disabled (simplified model)
H_KL = kohn_luttinger_hamiltonian(ny, dy, gamma1, gamma2, gamma3, with_mixing=False)
# Use sparse matrices for better performance with large grids
from scipy import sparse
# ... create matrices ...
result = sparse.csr_matrix(result) # Ensure correct sparse matrix typeTodas las órdenes se pueden copiar/pegar. Cambia rutas y números a tu caso.
# Mínimo razonable (ejemplo):
spintransport-sim \
--L_A 1200 --T_fs 108.9 --dy_A 1.0 --dt_fs 0.968 \
--E_min 0.0 --E_max 1.5 --nE 101 \
--gamma1 6.790 --gamma2 1.900 --gamma3 2.681 \
--Lb_A 20 --Vb_eV 0.3 --beta_eff_eVA 0.4 \
--out rashba_out
# Sin Rashba (control/chequeo analítico T+R≈1):
spintransport-sim ... --beta_eff_eVA 0.0 --out ctrl_no_rashba
# Barrera más gruesa y alta:
spintransport-sim ... --Lb_A 40 --Vb_eV 0.5 --out thick_high_barrier
# Malla de energías más densa:
spintransport-sim ... --nE 401 --out denseE
# Paso temporal más fino (más frames):
spintransport-sim ... --dt_fs 0.5 --T_fs 200 --out long_run# Layout dividido (HH arriba, LH espejo abajo); energía central (default):
spintransport-time-evolution --dir rashba_out --layout split
# Layout compartido (todas positivas), energía por índice:
spintransport-time-evolution --dir rashba_out --layout shared --energy-index 75
# Guardar snapshots (t=10, 50, 100) como PNGs:
spintransport-time-evolution --dir rashba_out --snap 10 --snap 50 --snap 100
# Guardar snapshots en carpeta y con DPI alto:
spintransport-time-evolution --dir rashba_out --snap 25 --snap-outdir rashba_out/snaps --png-dpi 220
# Estilo Matplotlib:
spintransport-time-evolution --dir rashba_out --layout split --style seaborn-v0_8-paper# MP4 default (requiere ffmpeg):
spintransport-export-mp4 --dir rashba_out
# Elegir energía por índice + layout split:
spintransport-export-mp4 --dir rashba_out --energy-index 50 --layout split
# Más fluido (fps) pero menos frames (stride):
spintransport-export-mp4 --dir rashba_out --fps 30 --stride 2
# Cambiar DPI y salida:
spintransport-export-mp4 --dir rashba_out --dpi 160 --outfile rashba_out/evolution_custom.mp4
# Control de codec/bitrate:
spintransport-export-mp4 --dir rashba_out --codec libx264 --bitrate 2500# GIF default:
spintransport-export-gif --dir rashba_out
# Layout compartido + energía:
spintransport-export-gif --dir rashba_out --layout shared --energy-index 20
# GIF ligero (menos frames, menos DPI):
spintransport-export-gif --dir rashba_out --stride 3 --fps 15 --dpi 100
# Guardar con nombre específico:
spintransport-export-gif --dir rashba_out --outfile rashba_out/evolution_E20.gif# T(E) solamente:
spintransport-plot-tr --dir rashba_out --mode T
# R(E) solamente:
spintransport-plot-tr --dir rashba_out --mode R
# T(E) (línea sólida) + R(E) (línea punteada) superpuestos:
spintransport-plot-tr --dir rashba_out --mode TR
# Limitar a un rango de índices de energía (10..60):
spintransport-plot-tr --dir rashba_out --mode TR --eindex-range 10 60# HH en región derecha, modo abs (baseline 0 hasta llegada):
spintransport-plot-precession --dir rashba_out --pair hh --region right --mode abs
# LH en barrera, modo cond (orientación local), energía central:
spintransport-plot-precession --dir rashba_out --pair lh --region barrier --mode cond
# Promedio sobre todas las energías:
spintransport-plot-precession --dir rashba_out --energy avg
# Energía única por índice:
spintransport-plot-precession --dir rashba_out --energy 37
# Promedio en rango de índices (10..30) y sin marcar llegada:
spintransport-plot-precession --dir rashba_out --energy 10:30 --no-mark
# Guardar como PNG con estilo:
spintransport-plot-precession --dir rashba_out --style seaborn-v0_8-paper --save rashba_out/precession.png# Reporte JSON con defaults (Ef = energía media de la malla si existe, T=300K):
spintransport-export-report --dir rashba_out
# Fijar Fermi y temperatura:
spintransport-export-report --dir rashba_out --Ef 0.12 --T 77
# Usar 2e^2/h (degeneración de spin efectiva):
spintransport-export-report --dir rashba_out --spin-deg
# Cambiar ruta de salida:
spintransport-export-report --dir rashba_out --out rashba_out/my_report.json# Resumen breve (Markdown) con defaults:
spintransport-export-summary --dir rashba_out
# Con Fermi/temperatura específicos:
spintransport-export-summary --dir rashba_out --Ef 0.12 --T 77
# 2e^2/h y salida personalizada:
spintransport-export-summary --dir rashba_out --spin-deg --out rashba_out/summary_v1.md