Hexagonal lattice special points "K" and "H" are wrong
Currently, the "K" and "H" symmetry points for hexagonal lattices (as provided by ase.dft.kpoints.get_cellinfo and also ase.dft.kpoints.get_bandpath) seem to be incorrect. A simple example that shows the incorrect behavior:
import matplotlib.pyplot as plt
from ase.lattice.hexagonal import Graphene
from ase.dft.kpoints import bandpath
atoms = Graphene('C', latticeconstant=(2.46, 15))
bp = bandpath('GKMG', atoms.cell, 30)
bp.plot()
plt.show()
I investigated this a bit and this error is due to the difference between lattice vectors where the in-plane basis vectors are at 60° or 120° to each other (reciprocal lattice vectors at 120° and 60°, respectively):
-
The
ibz_pointsdict inase.dft.kpointscontains special points for the hexagonal lattice that need the in-plane basis vectors of the unit cell to be at 60° to each other. Specifically, the K-point (-1/3, 1/3, 0) and H-point (-1/3, 1/3, 0.5) definitions rely on this. -
However, the hexagonal lattice generated by ASE (
ase.lattice.hexagonal) generates a unit cell where the in-plane lattice vectors are at 120° (reciprocal lattice at 60°). This is not commensurate with the ibz_points definition. In addition, the calculation of a Niggli-reduced cell (provided byase.build.tools.niggli_reduce_cell) automatically converts a lattice with a 60° angle to one with a 120° angle. This routine is called withinase.dft.kpoints.get_cellinfo, which converts all cells to an orientation that doesn't match theibz_pointsdict. Since commit 2c7e4bfd,ase.geometry.crystal_structure_from_cellclassifies both types of unit cells as a 'hexagonal' cell, causing a silent failure and incorrect values to be returned.
Since both the hexagonal generation routines and the Niggli-reduction procedure adopt the 120° angle convention, I propose to simply change the ibz_points dict to contain the values for the 120° unit-cell, i.e., 'K': [1 / 3, 1 / 3, 0] and 'H': [1 / 3, 1 / 3, 1 / 2] (removing the minus signs).
I verified this problem exists on the master branch and changing the ibz_points dict fixes the behavior.