k-point meshes¶
vibe-qc samples the Brillouin zone with a Monkhorst-Pack grid.
from vibeqc import monkhorst_pack
km = monkhorst_pack(sysp, mesh=[4, 4, 4])
print(len(km)) # 64 (full mesh)
print(km.kpoints[0]) # first k-point in Cartesian coords (bohr^-1)
print(km.weights[0]) # 1/64
The mesh argument says how many subdivisions along each reciprocal
axis. vibe-qc auto-clamps non-periodic axes to 1 k-point regardless of
the input:
# 1D system: mesh[1] and mesh[2] silently become 1.
km = monkhorst_pack(sysp_1d, [8, 4, 4]) # effectively [8, 1, 1]
IBZ reduction¶
Attach the space group first, then request symmetry reduction:
from vibeqc import attach_symmetry
attach_symmetry(sysp)
km = monkhorst_pack(sysp, [4, 4, 4], use_symmetry=True)
print(len(km)) # fewer — points related by crystal symmetry are merged
Note
The multi-k SCF drivers (run_rhf_periodic, run_rks_periodic)
currently use the full mesh, not the IBZ. Supporting IBZ in the SCF
requires the D(R) transformation matrices for basis-function pairs
under each symmetry operation; that’s on the roadmap as a performance
optimisation.
Choosing the mesh size¶
For insulators: start with 4 points per reciprocal axis, double until the total energy per unit cell stops changing. Rough guide:
System type |
Starting mesh |
|---|---|
Finite cluster in periodic box (molecular limit) |
[1, 1, 1] |
1D polymer |
[6, 1, 1] |
2D slab |
[6, 6, 1] |
3D wide-gap insulator |
[4, 4, 4] |
3D narrow-gap |
[8, 8, 8] |
Metal |
— not supported yet (requires smearing; see roadmap) |