Learning Objectives
Across this chapter you have built the entire conceptual machinery of reciprocal space — the duality condition, the Brillouin zone, Bloch's theorem, structure factors, k-point grids, and the Monkhorst–Pack prescription. This closing section answers a single, very practical question: where does each of those concepts actually live inside a VASP calculation?
By the end of the section you should be able to:
- Trace each of the five canonical VASP reciprocal-space artefacts — POSCAR, KPOINTS, IBZKPT, EIGENVAL, and DOSCAR — back to the exact mathematical object from this chapter that it represents.
- Read and write all four KPOINTS modes (automatic mesh, line-mode for band paths, explicit list, and generalised regular grid) and pick the right one for SCF, DOS, and band-structure calculations.
- Interpret VASP's IBZKPT file — including the integer weights — and verify that the irreducible point count matches what symmetry predicts.
- Use the rule of thumb (with in Å⁻¹) to pick a converged Monkhorst–Pack mesh from the lattice alone.
- Build a one-screen Python helper that converts any VASP POSCAR into a converged KPOINTS file — the same script you will reuse throughout Chapter 6 for the Mn:CdSe simulation.
One-line preview: every reciprocal-space concept in Chapter 3 has a textual analogue in a VASP file. POSCAR carries the real lattice and so implicitly carries ; KPOINTS picks ; IBZKPT records the symmetry reduction; EIGENVAL stores ; DOSCAR is the Brillouin-zone integral of those eigenvalues.
The Reciprocal-Space Tour of a VASP Run
Most VASP first-timers think of the program as a black box that consumes INCAR, POSCAR, POTCAR, and KPOINTS, and emits OUTCAR. From a reciprocal-space perspective, however, you can read the entire workflow as one Brillouin-zone integral taken apart into discrete steps. The next table is the index for the rest of this section.
| VASP file | What lives inside | Chapter 3 concept | Where covered |
|---|---|---|---|
| POSCAR | Direct lattice rows aᵢ in Å | Real basis. Implicitly fixes B = 2π·(A⁻¹)ᵀ. | §3.2 |
| OUTCAR (header) | Both A and B printed (B without 2π) | Reciprocal lattice as a verifiable object. | §3.2 |
| KPOINTS | Mesh density, centring, optional shifts; or a band path | Where in the BZ to sample. Monkhorst–Pack rule. | §3.8 — §3.9 |
| IBZKPT | Irreducible k-points and integer weights | Symmetry-reduced BZ. Wedge of the point group. | Chapter 2 + §3.3 |
| EIGENVAL | ε_n(k) for each band n at each irreducible k | Bloch eigenvalues — the values being summed. | §3.5 |
| DOSCAR | Density of states n(ε) and partial DOS | Brillouin-zone integral of δ(ε − ε_n(k)). | Chapter 5 |
| vasprun.xml | Structured XML containing all of the above | The one file post-processing tools really read. | Chapter 6 |
The mental model
Each row of the table is the same -information re-expressed in a different form: as a lattice (POSCAR), as a sampling rule (KPOINTS), as a list (IBZKPT), as eigenvalues (EIGENVAL), as an integrated spectrum (DOSCAR). When you read a VASP run, you are walking down this column.
POSCAR → A → B — The Implicit Reciprocal Lattice
VASP never asks you for explicitly. The program builds them on the fly from your POSCAR in the second line of subroutine latgen.f90 using exactly the closed-form recipe from §3.2: . The first thing OUTCAR prints back is the result, divided by , in units of Å⁻¹.
1direct lattice vectors reciprocal lattice vectors
2 0.000000000 3.038500000 3.038500000 -0.164554 0.164554 0.164554
3 3.038500000 0.000000000 3.038500000 0.164554 -0.164554 0.164554
4 3.038500000 3.038500000 0.000000000 0.164554 0.164554 -0.164554
5
6 length of vectors
7 4.298 4.298 4.298 0.285 0.285 0.285Multiply each printed reciprocal row by and you recover the textbook for FCC CdSe with . The columns match exactly.
A 2-second VASP sanity check
Open OUTCAR and grep for reciprocal lattice vectors. The three rows should have the same as your hand calculation to better than 1 part in 10⁵. If they don't, your POSCAR scale factor is wrong — the single most common typo new VASP users make.
Anatomy of the KPOINTS File
After the lattice itself, the KPOINTS file is the single most consequential reciprocal-space input you provide. It lives in a strict 5-line ASCII format, but those five lines encode four very different sampling strategies. Every working VASP practitioner can recognise all four on sight.
Mode 1 — Automatic Monkhorst–Pack mesh
The default, used for SCF and DOS calculations. The integer on line 2 is zero — the cue that lines 3–5 below describe a generator rather than an explicit list.
1Automatic mesh
20
3Gamma
412 12 12
50 0 0Reading top to bottom:
- Line 1. Free-form comment.
- Line 2. Number of k-points. 0 means "generate them automatically".
- Line 3. Centring keyword. Gamma (Γ-centred) places one point exactly on Γ. Monkhorst-pack shifts the entire mesh by half a step so Γ falls between points. For hexagonal lattices Γ-centred is mandatory; for cubic it is the safe default.
- Line 4. Mesh subdivisions along .
- Line 5. Additional fractional shift . Almost always 0 0 0; non-zero shifts are an advanced trick to break a symmetry on purpose.
Mode 2 — Line mode for band structures
For plotting along the high-symmetry path of §3.4, switch to line mode. Line 2 now sets how many k-points to interpolate per segment. Each consecutive pair of non-blank coordinate lines defines one segment.
1FCC band path Γ-X-W-L-Γ-K
220
3Line
4Reciprocal
50.000 0.000 0.000 ! Γ
60.500 0.000 0.500 ! X
7
80.500 0.000 0.500 ! X
90.500 0.250 0.750 ! W
10
110.500 0.250 0.750 ! W
120.500 0.500 0.500 ! L
13
140.500 0.500 0.500 ! L
150.000 0.000 0.000 ! Γ
16
170.000 0.000 0.000 ! Γ
180.375 0.375 0.750 ! KRead this as: from Γ to X interpolate 20 points; from X to W another 20; and so on along the standard Setyawan–Curtarolo path Γ–X–W–L–Γ–K. The keyword Reciprocal on line 4 tells VASP that the coordinates are fractional in units of — never confuse this with Cartesian, which expects Å⁻¹.
Modes 3 and 4 — Explicit lists and generalised grids
Less common, but you will eventually meet them. Explicit-list mode (line 2 set to a positive integer ) feeds VASP hand-picked k-points with weights — the format VASP itself uses to write IBZKPT. Generalised-grid mode (line 4 contains three reciprocal basis rows instead of three integers) lets you sample on a non-cubic-aligned grid; it is essentially how phonopy and related tools talk to VASP.
Choosing centring on a non-cubic system
For any lattice whose are not orthogonal — hexagonal, rhombohedral, monoclinic, triclinic — Monkhorst–Pack centring can place k-points off the symmetry axes, breaking degeneracies that the crystal actually has. Γ-centred is the correct default. The performance penalty is zero; the reduction in surprise is enormous.
KSPACING — the One-Line INCAR Alternative
The KPOINTS file is the classical interface, but it has one annoying feature: every time the cell shape changes (relaxation, equation of state, scan over lattice constant) the right mesh changes too, and you have to remember to regenerate KPOINTS. VASP's answer is the KSPACING tag, an INCAR option that builds the mesh on the fly from the current cell.
Set it once, in INCAR:
1# INCAR fragment
2KSPACING = 0.20 ! target spacing between k-points, in 1/Angstrom
3KGAMMA = .TRUE. ! Γ-centred mesh (mandatory for hex; recommended for cubic)VASP then generates a Γ-centred Monkhorst–Pack mesh whose subdivisions along each reciprocal axis are
That is exactly the inverse-volume rule from §3.8 expressed as a single number, and it carries the same physical meaning: keep the spacing between adjacent k-points constant in 1/Å, so a stretched cell (smaller ) automatically gets a sparser mesh and a compressed cell automatically gets a denser one. If you write KSPACING = 0.20 in INCAR and provide no KPOINTS file at all, VASP picks the mesh on its own; if you do provide a KPOINTS file, that file wins.
| KSPACING (Å⁻¹) | Roughly equivalent to ℓ in §3.8 | When to use |
|---|---|---|
| 0.40 | ℓ ≈ 16 Å⁻¹ | Insulator/semiconductor relaxation; coarse |
| 0.30 | ℓ ≈ 21 Å⁻¹ | Insulator total energy; safe default |
| 0.20 | ℓ ≈ 31 Å⁻¹ | Semiconductor DOS, defects, large supercells |
| 0.15 | ℓ ≈ 42 Å⁻¹ | Metals, magnetism, optical properties |
| 0.10 | ℓ ≈ 63 Å⁻¹ | Fermi-surface integrals, GW, hybrids |
Why two interfaces for the same thing?
The KPOINTS file gives you total control — line mode for band structures, explicit lists, generalised grids, custom shifts. KSPACING gives you total convenience — set one number, never regenerate. The community split is roughly: production throughput (high-throughput databases, AiiDA workflows, relaxation campaigns) uses KSPACING; per-system one-offs (a band structure for a paper) uses an explicit KPOINTS file. Use whichever matches the task; both produce identical numbers if you match .
KSPACING and band structures do not mix
Line-mode k-points cannot be auto-generated from KSPACING — it is an SCF-only convenience. If you want a band plot, you switch to an explicit KPOINTS file with Line-mode set, regardless of what is in INCAR. (This is the recipe in the next section.)
The IBZKPT File — Symmetry in Plain Text
After VASP reads KPOINTS it expands the mesh, applies every operation of the crystal's point group, and discards symmetry-equivalent points. The result is dumped into IBZKPT:
1Automatically generated mesh
2 72
3Reciprocal lattice
4 0.00000000 0.00000000 0.00000000 1
5 0.08333333 0.00000000 0.00000000 8
6 0.16666667 0.00000000 0.00000000 8
7 0.25000000 0.00000000 0.00000000 8
8 0.33333333 0.00000000 0.00000000 8
9 ...
10 Tetrahedra
11 6912 0.0000010851
12 1 1 2 3 ...The four columns mean exactly:
- Lines 1–2. Header. Line 2 is the count of irreducible k-points the run will actually evaluate. For a 12×12×12 mesh on FCC, with full Oh symmetry, this number is 72.
- Line 3. Coordinate type — almost always Reciprocal (fractional in ).
- Lines 4 onward. Three fractional coordinates followed by an integer weight equal to the size of that point's symmetry orbit.
The weights add up to — for a 12×12×12 mesh, 1 728. That is the integer identity which guarantees nothing has been double-counted when VASP later evaluates a BZ-average like
The sum runs only over the irreducible set, weighted by — that is the entire reason IBZKPT exists. VASP also writes a Tetrahedra block at the bottom; it is the connectivity list used by the Blöchl tetrahedron method (we will meet it again in Chapter 5 when computing DOS).
Reading the speedup
Divide the total mesh count by the irreducible count and you get the symmetry speedup. For 12×12×12 on FCC: 1 728 / 72 = 24× fewer Hamiltonian diagonalisations than a brute-force calculation. This factor scales like the order of the point group divided by 2 (the 2 is time-reversal symmetry, which VASP applies automatically when ISYM ≥ 1).
Interactive — Monkhorst–Pack Mesh in the BZ
The picture below is the geometric content of IBZKPT: the FCC Brillouin zone (truncated octahedron, §3.3) with every MP grid point folded into it. Amber dots are the irreducible representatives — the only ones VASP actually solves. Slate dots are the symmetry-equivalent partners that VASP knows about but never diagonalises. Slide the mesh density and watch the irreducible count grow far slower than the total — exactly the speedup the previous Tip just described.
Three things to try while you play with the slider:
- Set with Γ-centring. You should read64 total, 8 irreducible, ×8 reduction in the side panel — the textbook FCC numbers.
- Toggle Γ-centring off (Monkhorst shift). Watch the irreducible count change for odd meshes — the shift can accidentally place mesh points on a symmetry-violating site and the reduction factor drops.
- Push to 8. The grid now has 512 points but the irreducible set is still well under 50. This is the asymptotic regime where a denser mesh costs almost nothing — and the regime where you should run convergence tests in.
What this viewer is not
The reduction is computed with the full cubic point group (Oh, 48 elements). For a real Mn:CdSe supercell the substitutional Mn breaks Oh down to a smaller subgroup, and the irreducible count grows accordingly. VASP handles that automatically through ISYM; this viewer is the unbroken-symmetry baseline.
Reciprocal-Space Outputs — EIGENVAL, DOSCAR, vasprun.xml
Once the SCF cycle finishes (Chapter 4), VASP emits three reciprocal-space artefacts. None of them is hard to read by hand once you know the format.
EIGENVAL — Bloch eigenvalues per k-point
EIGENVAL pairs each irreducible k-point (with its weight) to the column of band energies . Skip the first six header lines and you find a repeating block: a blank line, the four-column k-point/weight row, then one line per band.
11 72 ...
2 <-- header lines
3
4 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.4629630E-03
5 1 -10.4321
6 2 -8.1245
7 3 -5.9871
8 ...
9
10 0.8333333E-01 0.0000000E+00 0.0000000E+00 0.3703704E-02
11 1 -10.2917
12 2 -7.9034
13 ...For the 12×12×12 CdSe mesh you would see 72 such blocks back to back. Plotting against the cumulative path length gives the band structure we will analyse in Chapter 5.
DOSCAR — Brillouin-zone integral
DOSCAR is the BZ integral of those eigenvalues:
Numerically this is the weighted sum over the irreducible set, broadened either by tetrahedra (the connectivity list at the bottom of IBZKPT) or by a Gaussian smearing of width SIGMA. The reciprocal-space bookkeeping is the same; only the broadening kernel changes.
vasprun.xml — the one file post-processors actually read
Tools like pymatgen, ase, sumo, and VASPKIT never look at OUTCAR; they parse vasprun.xml. The XML contains everything in the plain-text files plus the lattice, the k-mesh, and per-orbital projections — all under structured tags. If you ever automate post-processing, this is the file you target.
The Band-Structure Workflow — SCF → Non-SCF → Line Mode
Section 3.4 told us where to draw a band path; §3.10 has so far told us how to fill a single KPOINTS file. But a band-structure plot in VASP is the result of two VASP runs, not one — and the file that travels between them is the single most-misused file in this whole pipeline. The recipe is short, mechanical, and where 90 % of beginner band plots silently go wrong.
Why two runs?
The Hamiltonian depends on the self-consistent density , and in turn depends on the eigenstates through . The only honest way to find is to integrate over a uniform sample of the Brillouin zone — the dense Monkhorst–Pack mesh of §3.9. The line-mode path of §3.4, with all its k-points stacked along Γ–X–W–L–Γ–K, samples a single one-dimensional curve through the BZ and is useless for that integral. Run it self-consistently and you would converge to a density that thinks the Brillouin zone is a string instead of a volume.
The fix is the two-step pattern below, used by every band-structure tool and tutorial since the 1990s:
- SCF run on a dense MP mesh. Converge the density properly. Save it to CHGCAR.
- Non-SCF run on the line-mode path. Read CHGCAR, build from it once, and diagonalise at each path k-point without ever touching again.
The INCAR tag that does the magic is ICHARG = 11: tens digit 1 means "read CHGCAR", ones digit 1 means "do not update it". Pair that with LCHARG = .FALSE. in the band run (so VASP does not overwrite the carefully-converged CHGCAR that you just copied in) and you have the entire pattern in three lines.
The orchestration script — every line annotated
The bash script below runs the full workflow for FCC CdSe, end to end. Click any line to read the meaning of that command, the role of every flag, and what file it produces or consumes. The two critical lines — LCHARG = .TRUE. in the SCF INCAR and ICHARG = 11 in the band INCAR — are highlighted in their cards.
The four ways this workflow silently fails
- Forgetting LCHARG = .TRUE. in the SCF. CHGCAR is never written; the band run quietly falls back to a superposition of atomic densities and produces bands that look roughly right but mis-place every avoided crossing.
- Different ENCUT in the two runs. The plane-wave basis size is set by ENCUT, and CHGCAR is stored on a grid sized to match. VASP refuses to read a CHGCAR whose grid does not match the current ENCUT — but the error message is short and easy to miss in a 30-MB OUTCAR.
- Using KSPACING in the band INCAR. KSPACING auto-generates a Monkhorst–Pack mesh and ignores the line-mode KPOINTS file entirely. You will get a dense uniform sampling and no band path. Either remove KSPACING or set it higher than the path will ever reach.
- ICHARG = 1 instead of 11. ICHARG = 1 reads CHGCAR and runs SCF on top of it on the line-mode path — which converges to a wrong density (string instead of volume) and gives wrong bands. Always 11 for the band run.
From this point onward
Every band-structure plot you see for the rest of this book — the gap engineering of §5.3, the orbital-projected bands of §5.4, the Mn:CdSe defect bands of Chapter 7 — is generated by exactly this two-run pattern. Internalise it once and you will read those plots as the natural output of one converged density and one frozen-density diagonalisation.
End-to-End Recipe — POSCAR to KPOINTS in Python
Putting the chapter together: given any POSCAR, build a converged KPOINTS file in one screen of Python. The script below does it for the FCC CdSe primitive cell and prints the diagnostics you should always check before launching a VASP run. Click any line to see the values flowing through it.
Running the script in the same directory as the CdSe POSCAR prints:
1|a_i| = [4.297 4.297 4.297] angstrom
2|b_i| = [1.791 1.791 1.791] 1/angstrom
3Mesh : (12, 12, 12)and writes the five-line KPOINTS file from Mode 1 above. Three things worth taking with you from this listing:
- The reciprocal lattice is one line of NumPy. B = 2*np.pi*np.linalg.inv(A).T is the entire content of §3.2.
- Convergence is one rule of thumb. covers the 90 % case. For the harder 10 % (defects, surfaces, metals), do an explicit -vs-energy convergence sweep — it is the first project of Chapter 6.
- The KPOINTS format is unforgiving. One stray space, a missing line, or the wrong centring keyword and VASP fails with a cryptic error. Always read the file you wrote with cat KPOINTS before launching.
Practical Recipe for the Mn:CdSe Target
The end-game of this book is a Mn-doped CdSe quantum-dot calculation. Reciprocal-space settings change as the cell grows. The table below is a cheat sheet you will return to in Chapter 6.
| Calculation stage | Cell | Mesh density (ℓ) | Resulting KPOINTS |
|---|---|---|---|
| Bulk SCF (primitive) | FCC primitive, a = 6.077 Å | ℓ = 20 Å⁻¹ — moderate | 12 × 12 × 12 Γ-centred |
| Bulk DOS / band structure | Same primitive | ℓ = 30 Å⁻¹ — tight | 16 × 16 × 16 SCF, then line mode |
| 2×2×2 supercell (clean) | Conventional 64-atom cube, a ≈ 12.15 Å | ℓ = 20 Å⁻¹ | 6 × 6 × 6 Γ-centred |
| 2×2×2 + 1 Mn substitution | Same supercell | ℓ = 20 Å⁻¹ | 4 × 4 × 4 Γ-centred (lower symmetry) |
| 3×3×3 supercell (Mn isolation) | 216-atom cube, a ≈ 18.23 Å | ℓ = 18 Å⁻¹ | 3 × 3 × 3 Γ-centred |
| Optical absorption tensor | Same as the SCF cell | ℓ = 40 Å⁻¹ | Doubled in each direction |
Why does the mesh get coarser as the cell grows?
Because real-space cell size and reciprocal-space mesh density are inversely related (§3.2). Doubling the supercell halves , so half as many subdivisions reach the same target. The total number of irreducible k-points falls roughly like for a fixed convergence target — which is the reason supercell calculations are tractable in practice.
Common Pitfalls
| Pitfall | Symptom | Fix |
|---|---|---|
| Wrong centring for hexagonal cell | VASP warning: 'k-mesh breaks symmetry of crystal'. | Use the Gamma keyword on line 3 of KPOINTS for any non-cubic system. |
| Confusing Reciprocal vs Cartesian in line mode | Band structure looks plausible but the high-symmetry labels are wrong. | Use Reciprocal coordinates for line mode unless you have a very specific reason. |
| Missing the 2π in OUTCAR comparison | Hand-derived |b_i| differs from OUTCAR by exactly 2π. | OUTCAR prints b_i / (2π). Multiply by 2π before comparing to a textbook formula. |
| Mesh too coarse for a metal | Total energy oscillates as the mesh increases. | Metals need finer meshes (ℓ ≥ 50) and Methfessel–Paxton smearing. Insulators tolerate ℓ ≈ 20. |
| Re-using bulk KPOINTS for a defect supercell | Calculation runs for a week. Wrong physics. | Scale the mesh inversely with supercell size. The Python recipe above does this automatically. |
| Lower symmetry than expected | IBZKPT has many more irreducible points than a textbook table predicts. | Symmetry-breaking impurities (Mn substitution) reduce the point group. Check the SYMMETRY block in OUTCAR. |
Summary
- Every reciprocal-space concept of Chapter 3 has a textual analogue in a VASP file. POSCAR carries the real basis (and so implicitly ); KPOINTS picks ; IBZKPT records the symmetry reduction; EIGENVAL stores ; DOSCAR is the BZ integral.
- OUTCAR's reciprocal-lattice header is — the crystallographer convention. Multiply by to recover the physics-textbook .
- KPOINTS has four modes — automatic, line, explicit, generalised. SCF and DOS use automatic; band structures use line mode along the Setyawan–Curtarolo path.
- IBZKPT integer weights add up to . The symmetry speedup over a brute-force calculation is the order of the point group divided by 2 — typically ×24 for cubic systems.
- The convergence rule of thumb with covers most insulator and semiconductor calculations. Metals need .
- One screen of NumPy converts any POSCAR into a converged KPOINTS file. The script you built here returns in Chapter 6 as the first step of every Mn:CdSe simulation.
Coming next: Chapter 4 — Quantum Mechanics for Solids — where we open the box VASP has been hiding behind: why does each k-point produce a column of eigenvalues in the first place? Free electrons, nearly-free electrons, tight binding, and the Kohn–Sham equations all wait on the other side.