The converged k-point mesh for 17,757 MC3D structures, measured with Quantum
ESPRESSO pw.x self-consistent-field calculations over a k-mesh sweep.
One row per structure: the converged mesh, taken as the first of three consecutive meshes on the structure's k-mesh ladder whose total energies agree within 1 meV per atom. Convergence is judged on energy alone; no force criterion is applied.
No spin polarisation. SSSP PBEsol pseudopotentials. Every mesh is unshifted and therefore Gamma-inclusive.
CIF_files/<source_db_id>.cifThe archive holds 18,220 structures while the table has 17,757 rows: 463
structures were calculated but never met the criterion within the range of
meshes swept, so they have a structure file and no converged answer. Join on
source_db_id and expect the shortfall rather than treating it as missing data.
<id>.cif in the archivek_mesh, in inverse
Angstrom, written [upper, lower) with the larger value first(k1, k2, k3)k_mesh and k_dist_interval are strings; a loader parses them rather than
reading numbers straight out of the column.
A mesh corresponds to an interval of k-distance, not a single value: every
k-distance in k_dist_interval yields the same mesh. The interval is written
larger value first, because a larger k-distance means a coarser mesh. Rung 1's
interval is [inf, x): every k-distance above max(|b_i|) gives (1, 1, 1).
If you train on a single k-distance, state which end of the interval you took —
the two ends are different numbers for the same mesh.
k_index is a position on an ordered ladder of the meshes a structure admits.
It is 1-based, and rung 1 is the Gamma-only (1, 1, 1) mesh. Each step up is
the next denser mesh the reciprocal lattice admits. Read the base from this
record; do not assume it.
The ladder is built from the k-distances at which the mesh changes. With
mesh_i = ceil(|b_i| / k_distance) — the VASP KSPACING convention, where
|b_i| includes the 2*pi factor — axis i steps from n to n + 1 exactly at
k_distance = |b_i| / n. Those quotients, over all three axes, sorted
descending, are the only distances where the mesh can change; each interval
between neighbours is one rung, and the mesh is read at the interval's midpoint.
The resolution floor. Quotients are enumerated down to
min_k_distance = 0.03 inverse Angstrom and no further, so the ladder ends at a
mesh of roughly ceil(|b_i| / 0.03) per axis. The floor is the same on every
axis, so all three axes stop at the same k-distance: every change point on
[0.03, inf) is present, and the ladder is a complete, gap-free set of meshes
over that whole range. Consecutive rungs differ by one k-point on at least one
axis and never by more than one on any axis.
Repeated meshes are dropped. When two axes have equal |b_i| their change
points coincide and two adjacent intervals can yield the same mesh; the ladder
keeps that mesh once, so a mesh never takes two k_index values.
k_index in this table spans rungs 1 to 42. Lowering min_k_distance only
appends rungs and never renumbers an existing one, so these values stay valid
under a smaller floor; a k_index computed under a different floor is
comparable only where the two ranges overlap. Any recomputation must state the
floor it used.
k_index is reproducible from the structure alone.
import math
from pymatgen.core import Structure
MIN_K_DISTANCE = 0.03
def k_distance_to_mesh(lengths, d):
return tuple(max(1, math.ceil(round(x / d, 5))) for x in lengths)
def kmesh_ladder(structure, min_k_distance=MIN_K_DISTANCE):
r = structure.lattice.reciprocal_lattice # includes 2*pi
lengths = (r.a, r.b, r.c)
cands = sorted(
{
round(x / n, 8)
for x in lengths
for n in range(1, max(1, math.floor(x / min_k_distance)) + 1)
},
reverse=True,
)
probes = [k_distance_to_mesh(lengths, cands[0] + 1.0)]
probes += [
k_distance_to_mesh(lengths, 0.5 * (hi + lo))
for hi, lo in zip(cands[:-1], cands[1:])
]
ladder, seen = [], set()
for mesh in probes:
if mesh in seen:
continue
seen.add(mesh)
ladder.append(mesh)
return ladder # ladder[i] is rung i + 1
ladder = kmesh_ladder(Structure.from_file("CIF_files/100115.cif"))
assert ladder[0] == (1, 1, 1)
ladder.index((14, 14, 8)) + 1 # -> 21
The same construction is maintained in
stfc/goldilocks-data
(goldilocks_data.kmesh) and
stfc/goldilocks-core; the sweep and
the labelling that produced this table are in goldilocks-data.
CC BY 4.0. See LICENSE.