mat-edi-mobility
SkillDev toolsCompute defect-limited carrier mobility and electron-defect scattering matrix elements in 2D and 3D semiconductors from first principles with Quantum ESPRESSO and the EDI plugin.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the mat-edi-mobility skill
What this skill tells your AI
The instructions your AI receives, as published by learningmatter-mit/atomisticskills in .agents/skills/mat-edi-mobility/SKILL.md and read by ahel’s review.
Goal
To compute the point-defect-limited carrier mobility $\mu(T)$ of a semiconductor and the underlying electron-defect scattering matrix elements $M(\mathbf{k}i, \mathbf{k}f) = \langle \psi{\mathbf{k}i} | \Delta V | \psi{\mathbf{k}f} \rangle$ from first principles, using the supercell difference-potential method of the Quantum ESPRESSO + EDI pipeline. Here $\Delta V = V{\text{defect}} - V{\text{pristine}}$ is the Kohn-Sham perturbation potential of an isolated point defect, extracted as the difference between the potentials of a defect-containing supercell and a pristine supercell. The matrix elements are computed on a coarse k-grid, transformed to a maximally localized Wannier basis $M(\mathbf{R}, \mathbf{R}')$, and interpolated onto dense fine grids. The state-resolved scattering rate follows from Fermi's golden rule,
$$\frac{1}{\tau_{n\mathbf{k}}} = \frac{2\pi}{\hbar}, n_{\text{d}}, \frac{1}{N_{\mathbf{k}}} \sum_{m,\mathbf{k}'} |M_{n\mathbf{k}, m\mathbf{k}'}|^2, \delta(\varepsilon_{n\mathbf{k}} - \varepsilon_{m\mathbf{k}'}),$$
and the mobility from the linearized Boltzmann transport equation in the self-energy (SERTA) and momentum (MRTA) relaxation-time approximations. The three first-class outputs are the direct matrix elements $M$ on the coarse grid, the Wannier-interpolated $M$ on a fine k-path, and the final mobility $\mu(T)$.
Background
Defect-limited transport requires $M(\mathbf{k}i, \mathbf{k}f)$ on k-grids far
denser than any tractable supercell calculation can supply. EDI solves this the
way EPW solves the electron-phonon problem: compute $M$ directly on a coarse grid
commensurate with the supercell, rotate into a Wannier basis where
$M(\mathbf{R}, \mathbf{R}')$ decays rapidly with $|\mathbf{R}|$ and $|\mathbf{R}'|$,
and interpolate to $300\times300$ or denser at negligible cost. The scattering
rate scales linearly with the defect concentration $n{\text{d}}$ (dilute,
incoherent-defect limit), so **the mobility scales as $1/n{\text{d}}$ and the
concentration must always be reported alongside $\mu$**. For 2D materials the
pristine and defect supercells are computed independently, so their electrostatic
potentials carry an arbitrary offset that must be removed by vacuum-level
alignment (pot_align = 'vacuum').
This skill is the defect-scattering companion to mat-epw-mobility, which computes the phonon-limited mobility. At finite temperature the two channels combine by Matthiessen's rule, $1/\mu_{\text{total}} = 1/\mu_{\text{phonon}} + 1/\mu_{\text{defect}}$. Defect energetics (formation energies, charge states) that set which defects dominate come from mat-defect-energy; the AMSET route in mat-dft-electronic-transport is an alternative phonon-limited channel.
External binary: building Quantum ESPRESSO 7.5 + EDI
EDI is an in-tree plugin of Quantum ESPRESSO, not a standalone code: it links QE's compiled static libraries and must be built against a matching QE version.
-
Obtain QE 7.5 (GitLab tag archive; no ReleasePack is required —
make w90auto-fetches the pinned Wannier90 submodule even from a tarball) and configure it. -
Clone EDI into the QE root and build:
# Requires: Quantum ESPRESSO 7.5 + EDI (external MPI build) cd <QE-root> make pw make w90 git clone https://github.com/yuanyue-liu-group/EDI edi-code cd edi-code && makeThis produces
src/edi.x(MPI) andsrc/extract_pot.x(serial). -
gfortran patch (required for GCC builds):
ed_coarse.f90contains lines up to 158 characters, so add long-line support toedi-code/src/makefileafter theincludeline:F90FLAGS += -ffree-line-length-none FFLAGS += -ffree-line-length-none -
extract_pot.xsegfault patch (required):extract_pot.f90callsclean_pw(.TRUE.)at line 77, before anyread_file, which segfaults on a fresh process. Comment it out (or delete that line) and rebuild:! CALL clean_pw(.TRUE.) ! upstream bug: runs before any read_file, segfaults
Pseudopotentials for the worked example are PseudoDojo NC-SR v0.5 PBE stringent
(https://www.pseudo-dojo.org/pseudos/nc-sr-05_pbe_stringent_upf.tgz); the Mo and
S UPFs are used as Mo.upf and S.upf. QE 7.5 must be built with Wannier90.
Instructions
[!IMPORTANT] Quantum ESPRESSO (
pw.x) and EDI (edi.x,extract_pot.x) are external compiled MPI binaries, exactly as VASP is in mat-dft-vasp. This skill targets a source build of QE 7.5 + EDI v2.0 (repomain@41fed72) with PseudoDojo NC-SR v0.5 PBE stringent pseudopotentials. The# Env: base-agentannotations apply only to the Python parser scripts. Reference input decks for every step are inresources/inputs/. Replace<ranks>with your MPI rank count;mpirun -npandsrun -nare interchangeable. Setpseudo_dirin each deck to your UPF directory (the decks use./pseudo/).
The pipeline is a DAG. The two supercell SCFs (step 3) are independent of the primitive cell and of each other and can run in parallel. Steps 5 and 6 must run in order (6 reads the Wannier archive written by 5).
1. Primitive-cell SCF
Compute the ground-state charge density of the pristine primitive cell.
assume_isolated = '2D' truncates the out-of-plane Coulomb tail and must be
consistent across every calculation. Deck:
resources/inputs/scf_primitive.in.
# Requires: Quantum ESPRESSO 7.5 + EDI (external MPI build)
mpirun -np <ranks> pw.x -nk <pools> < scf_primitive.in > scf_primitive.out
Confirm convergence has been achieved.
2. Primitive-cell NSCF on the explicit coarse grid
Produce the Bloch states EDI folds into Wannier functions. The grid must be an
explicit K_POINTS crystal list (never automatic) and its dimensions must
equal coarse_nk1/nk2/nk3 in the EDI input (12x12x1 here). Generate the list
with the helper, then splice it into the NSCF deck
(resources/inputs/nscf_primitive.in
already contains the 144-point 12x12x1 card):
# Env: base-agent
python .agents/skills/mat-edi-mobility/scripts/gen_kgrid.py 12 12 1
# Requires: Quantum ESPRESSO 7.5 + EDI (external MPI build)
mpirun -np <ranks> pw.x -nk <pools> < nscf_primitive.in > nscf_primitive.out
nbnd (17 here) must cover the disentanglement window (the 5 kept bands 13-17).
Note: the upstream example ships an 18x18x1 NSCF that is inconsistent with its
coarse_nk1 = 12; this deck fixes that to 12x12x1.
3. Pristine and defect supercell SCFs
Compute the Kohn-Sham potentials whose difference is $\Delta V$. Both are
Gamma-only SCFs of a 6x6x1 supercell (108 atoms pristine; 107 with one S vacancy).
The supercell lattice vectors must be exact integer multiples of the primitive
cell and host-atom positions must fold back to the primitive sites, or $\Delta V$
is corrupted. Relax the defect supercell before this final SCF. Decks:
resources/inputs/scf_pristine_super.in,
resources/inputs/scf_defect_super.in.
# Requires: Quantum ESPRESSO 7.5 + EDI (external MPI build)
mpirun -np <ranks> pw.x < scf_pristine_super.in > scf_pristine_super.out
mpirun -np <ranks> pw.x < scf_defect_super.in > scf_defect_super.out
4. Extract the difference potential
Run the serial extract_pot.x to write the pristine and defect local KS
potentials as cube files (V_p.cube, V_d.cube) on the supercell real-space
grid. Deck: resources/inputs/extract_pot.in.
# Requires: Quantum ESPRESSO 7.5 + EDI (external MPI build)
mpirun -np 1 extract_pot.x < extract_pot.in > extract_pot.out
extract_pot.x is serial; run it with a single rank.
5. First EDI pass: direct matrix elements + Wannierization
Compute $M(\mathbf{k}_i, \mathbf{k}_f)$ directly on the coarse 12x12x1 grid,
build $M(\mathbf{R}, \mathbf{R}')$, run the Wannier90 minimization, and write the
Wannier archive mos2_edmatw_2d.bin that the transport pass reuses. Deck:
resources/inputs/edi_setup.in
(edwread = .false., wannierize = .true., do_transport = .false.).
# Requires: Quantum ESPRESSO 7.5 + EDI (external MPI build)
mpirun -np <ranks> edi.x -nk <ranks> -i edi_setup.in > edi_setup.out
Key namelist variables:
nbndsub = 5,proj(1) = 'Mo:d',bands_skipped = 'exclude_bands = 1-12'— the 5-band Mo-d Wannier manifold; material-specific.dis_win_min/max,dis_froz_min/max— outer and frozen disentanglement windows (eV); set them around the transport bands.wdata(1) = 'guiding_centres = .true.'— required in long-vacuum 2D cells or the Wannier centres fold to a wrong z-image.coarse_nk*must equal the step-2 NSCF grid;fine_nk*sets the interpolation grid.edmat_interp_from_file = .true.withfilki_interp/filkf_interpalso writes the interpolated $M$ along the validation path (mos2_edmat_interp.dat), used in 6b.
Because it also computes the coarse-grid Bloch $M$, this pass writes the direct
matrix elements to mos2_edmat_bloch.dat (columns: iki ikf kix kiy kiz kfx kfy kfz ibnd jbnd |M|^2 Re(M) Im(M) |M_loc|^2 |M_nl|^2).
-nk <ranks> (pools = rank count) is recommended for EDI performance.
6. Second EDI pass: fine-grid interpolation + BTE transport
Interpolate $M$ onto the fine grid and solve the BTE for $\mu(T)$. This pass reuses
the Wannier archive (edwread = .true., wannierize = .false.,
do_transport = .true.). Deck:
resources/inputs/edi_transport.in.
# Requires: Quantum ESPRESSO 7.5 + EDI (external MPI build)
mpirun -np <ranks> edi.x -nk <ranks> -i edi_transport.in > edi_transport.out
Key transport variables:
fine_nk1 = fine_nk2 = 300— production grid;48is a fast smoke test.transport_win_min/max— narrow energy window (eV) around the carrier band edge; only pocket states scatter.carrier_conc(cm^-2 in 2D) sets the Fermi level by bisection;defect_conc(cm^-2 in 2D) scales the rate. Mobility scales as $1/$defect_conc— report it.delta_method = 'gaussian',delta_sigma = 0.01— energy-conserving delta; also'triangular'(2D optimized) and'adaptive'(velocity-dependent smearing).temps(i),nstemp— temperature list.
Outputs: mos2_transport.dat (T mu_SERTA_xx mu_MRTA_xx mu_SERTA_yy mu_MRTA_yy
in cm^2/Vs) and mos2_inv_tau.dat (state-resolved
ik ibnd E inv_tau_SERTA inv_tau_MRTA tau_SERTA tau_MRTA). Parse them:
# Env: base-agent
python .agents/skills/mat-edi-mobility/scripts/parse_transport.py mos2_transport.dat --output-dir results/
python .agents/skills/mat-edi-mobility/scripts/parse_inv_tau.py mos2_inv_tau.dat --output-dir results/
Fine-grid convergence is cheap to sweep: because edwread = .true. reuses
mos2_edmatw_2d.bin, each rerun redoes only the interpolation + BTE (seconds to a
few minutes, e.g. ~6 s at 48x48 up to ~3 min at 300x300 for this example). The
outputs are prefix-named (mos2_transport.dat), so copy them to a per-grid name
between reruns. Converge fine_nk* before trusting $\mu$: a 48x48 smoke grid runs
21-23% low here.
6b. Validate: direct vs Wannier-interpolated M on a k-path
Confirm the Wannier interpolation reproduces the directly computed $M$ (this is the
interpolation's correctness gate, analogous to the DFPT-vs-EPW $|g|$ benchmark in
mat-epw-mobility). Both are evaluated on the SAME
k-path: one initial point at K (resources/inputs/ki.dat)
and a 300-point Gamma-K-M-Gamma final path
(resources/inputs/kf.dat). Deck:
resources/inputs/edi_direct.in, which enables
both edmat_interp_from_file and edmat_direct_from_file on the same path.
Direct mode needs NSCF wavefunctions at every path k-point — the coarse 12x12x1 NSCF only contains 8 of the 300 path points. Run it in two steps:
- Launch the direct pass once. It detects the missing k-points, auto-writes
nscf_custom.inlisting exactly the ki + kf points it needs, and aborts. - Run that NSCF into a separate save tree (e.g.
primitive_path/dout/; ~1.5 min on 32 tasks for the 301-point path here), pointedi_outdirat it (already set to../primitive_path/dout/in the deck), and rerun the direct pass (~3m40s at 32 ranks x 4 cores for this example — direct mode is memory-heavier; see Constraints).
# Requires: Quantum ESPRESSO 7.5 + EDI (external MPI build)
# 1. First attempt writes nscf_custom.in and stops:
mpirun -np <ranks> edi.x -nk <ranks> -i edi_direct.in > edi_direct.out
# 2. Run the path NSCF into primitive_path/, then rerun the direct pass:
mpirun -np <ranks> pw.x < nscf_custom.in > nscf_custom.out # stage into primitive_path/dout/
mpirun -np <ranks> edi.x -nk <ranks> -i edi_direct.in > edi_direct.out
This writes mos2_edmat_direct.dat (direct $M$, absolute NSCF band indices) and
mos2_edmat_interp.dat (interpolated $M$, Wannier-subspace indices 1-5). Compare:
# Env: base-agent
python .agents/skills/mat-edi-mobility/scripts/parse_edmat.py mos2_edmat_interp.dat --output-dir results/
python .agents/skills/mat-edi-mobility/scripts/compare_edmat.py mos2_edmat_direct.dat mos2_edmat_interp.dat --band-offset 12 --band-sum --output-dir results/
--band-offset 12 maps the two files' band conventions (direct = interp + number
of excluded bands). --band-sum compares the gauge-invariant band-summed
$\sum_{mn} |M_{mn}|^2$ per k-point — the meaningful metric, since individual band
pairs mix under the arbitrary Wannier gauge along band crossings (drop the flag
for the pairwise statistics). A small relative RMS confirms the
interpolation. Finally, benchmark $\mu(T)$ against the upstream reference with
compare_reference.py (see the example).
Examples
See examples/mos2-s-vacancy/ for the full
end-to-end run on a sulfur vacancy in monolayer MoS2, including the coarse-grid
direct $M$, the Wannier-interpolated $M$ with the direct-vs-interpolated
comparison, the mobility-vs-temperature table validated against the upstream
reference outputs, and a literature cross-check against ACS Nano 18, 8511 (2024).
Constraints
- External codes: requires an MPI build of Quantum ESPRESSO 7.5 with Wannier90
and the EDI plugin built in-tree (
edi.x,extract_pot.x); the Python parsers run inbase-agent. GCC builds require-ffree-line-length-none(see Background). Version pins reflect what was targeted, not a claim that other versions are broken. - In-tree build only: EDI links QE 7.5 static libraries; the QE version must match exactly. Our QE 7.4.1 build is not reusable.
- Point defects only: EDI v2.0 handles point defects (vacancies, substitutions, interstitials). Extended defects (surfaces, grain boundaries) are not yet supported.
- SERTA / MRTA, not iterative BTE: mobility is relaxation-time-based; there is no self-consistent iterative BTE solution.
- Mobility scales with defect concentration: $\mu \propto 1/$
defect_concin the dilute limit — always report the concentration alongside $\mu$. - 2D systems need
assume_isolated = '2D'(vacuum-separated cell, c = 24 A here) in everypw.xrun andpot_align = 'vacuum'in EDI, consistently. - Coarse-grid match: the primitive NSCF grid must equal
coarse_nk1/nk2/nk3, and the NSCF must use an explicitK_POINTS crystallist, or the Wannier folding is inconsistent. - Supercell consistency: supercell lattice vectors must be exact integer multiples of the primitive cell, host atoms must fold to primitive sites, and the FFT grid must be commensurate, or $\Delta V$ is corrupted.
- Memory scales with supercell volume x ranks-per-node: in the setup, transport,
and direct modes every MPI rank holds the full supercell real-space potentials
($V_d$, $V_p$, $V_{\text{colin}}$) — about 2 GB/rank for this 6x6 MoS2 example
(240x240x300 FFT grid), and direct mode holds an extra copy. On ~2 GB/core clusters,
under-subscribe the node: run setup/transport at half ranks
(
--ntasks=64 --cpus-per-task=2,edi.x -nk 64) and direct mode at a quarter (--ntasks=32 --cpus-per-task=4,edi.x -nk 32). Symptom of getting it wrong: the job staysRUNNINGwith the output frozen right after theFull double-FTbanner while ranks are silently OOM-killed and survivors deadlock in the next MPI collective. CPU burn does not prove progress — check output-file mtime and live task count. - Material-specific inputs:
ecutwfc,nbnd,nbndsub, projections,exclude_bands, and the disentanglement/transport windows are set for MoS2 and must be adapted to your material and band manifold.
References
- Z. Xiao, R. Guo, C. Zhang, Y. Liu, "Point Defect Limited Carrier Mobility in 2D Transition Metal Dichalcogenides", ACS Nano 18, 8511 (2024). DOI
- I.-T. Lu, J.-J. Zhou, M. Bernardi, "Efficient ab initio calculations of electron-defect scattering and defect-limited carrier mobility", Phys. Rev. Materials 3, 033804 (2019). DOI
- I.-T. Lu, J. Park, J.-J. Zhou, M. Bernardi, "Ab initio electron-defect interactions using Wannier functions", npj Comput. Mater. 6, 17 (2020). DOI
- A. A. Mostofi, et al., "An updated version of wannier90: A tool for obtaining maximally-localised Wannier functions", Comput. Phys. Commun. 185, 2309 (2014). DOI
- P. Giannozzi, et al., "Quantum ESPRESSO toward the exascale", J. Chem. Phys. 152, 154105 (2020). DOI
- The EDI code paper is in preparation; cite the repository: github.com/yuanyue-liu-group/EDI.
Author: Chenmu Zhang Contact: GitHub @cz2014
Signals
- GitHub stars
- 164
- Forks
- 24
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
mat-edi-mobility- Source
- github.com/learningmatter-mit/atomisticskills