Hi,
I got confused about kppvol, kppa and reciprocal_density, which are used in pymatgen.
kppvol is an input argument of the below automatic_density_by_vol
def automatic_density_by_vol(structure, kppvol, force_gamma=False):
"""
Returns an automatic Kpoint object based on a structure and a kpoint
density per inverse Angstrom^3 of reciprocal cell.
Algorithm:
Same as automatic_density()
Args:
structure (Structure): Input structure
kppvol (int): Grid density per Angstrom^(-3) of reciprocal cell
force_gamma (bool): Force a gamma centered mesh
Returns:
Kpoints
"""
vol = structure.lattice.reciprocal_lattice.volume
kppa = kppvol * vol * structure.num_sites
return Kpoints.automatic_density(structure, kppa, force_gamma=force_gamma)
kppa is the input arguement of automatic_density
def automatic_density(structure, kppa, force_gamma=False):
“”"
Returns an automatic Kpoint object based on a structure and a kpoint
density. Uses Gamma centered meshes for hexagonal cells and
Monkhorst-Pack grids otherwise.
Algorithm:
Uses a simple approach scaling the number of divisions along each
reciprocal lattice vector proportional to its length.
Args:
structure (Structure): Input structure
kppa (int): Grid density
force_gamma (bool): Force a gamma centered mesh (default is to
use gamma only for hexagonal cells or odd meshes)
Returns:
Kpoints
"""
comment = "pymatgen v%s with grid density = %.0f / number of atoms" % (__version__, kppa)
if math.fabs((math.floor(kppa ** (1 / 3) + 0.5)) ** 3 - kppa) < 1:
kppa += kppa * 0.01
latt = structure.lattice
lengths = latt.abc
ngrid = kppa / structure.num_sites
mult = (ngrid * lengths[0] * lengths[1] * lengths[2]) ** (1 / 3)
num_div = [int(math.floor(max(mult / l, 1))) for l in lengths]
is_hexagonal = latt.is_hexagonal()
has_odd = any([i % 2 == 1 for i in num_div])
if has_odd or is_hexagonal or force_gamma:
style = Kpoints.supported_modes.Gamma
else:
style = Kpoints.supported_modes.Monkhorst
return Kpoints(comment, 0, style, [num_div], [0, 0, 0])
reciprocal_density is the input argument of MPStaticSet. In the documentation, it is explained as follows:
reciprocal_density (int): For static calculations, we usually set the reciprocal density by volume. This is a convenience arg to change that, rather than using user_kpoints_settings. Defaults to 100, which is ~50% more than that of standard relaxation calculations.
I have read the document and definition many times, but still have a few questoins as below. Appreciate it if you can help me out with them!
Question 1: In automatic_density_by_vol, kppa = kppvol * vol * structure.num_sites
, where the number of atoms is multiplied. But why is kppa still per atom as shown in variable comment in atuomatic_density: comment = 'pymatgen v%s with grid density=%.0f/atom' % (__version__, kppa)
? variable comment
says that kppa
is grid density. In the document of automatic_density_by_vol
, However, kppvol is explained as Grid density per Angstrom^(-2) of reciprocal cell. So should it be kppa=kppvol * vol
instead?
Question 2: in automatic_density, variable ngrid is introduced: ngrid=kppa / structure.num_sites
. Should it be ngrid=kppa*struture.num_sites
to cancel the unit of per atom
?
Question 3: In the official document of Materials Project, it is documented that total energies are calculated using a k-point mesh of 1000 per reciprocal atom (pra). Does it mean the variable reciprocal_density
of MPStaticSet
equals 1000?
Question 4: Is the variable reciprocal_density
of MPStaticSet
exactly the variable kppvol
of automatic_density_by_vol
?
Thanks very much for your help!
Merry Christmas!
Best regards,
Yang Tong