Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some Kpoints generated using wrong mesh types #3245

Merged
merged 6 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pymatgen/analysis/chemenv/utils/scripts_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ def compute_environments(chemenv_configuration):
input_source = input('Enter materials project id (e.g. "mp-1902") : ')
from pymatgen.ext.matproj import MPRester

mpr = MPRester()
structure = mpr.get_structure_by_material_id(input_source)
with MPRester() as mpr:
structure = mpr.get_structure_by_material_id(input_source)
lgf.setup_structure(structure)
print(f"Computing environments for {structure.composition.reduced_formula} ... ")
se = lgf.compute_structure_environments(maximum_distance_factor=max_dist_factor)
Expand Down
36 changes: 18 additions & 18 deletions pymatgen/cli/pmg_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,44 @@ def do_query(args):
"""
from pymatgen.ext.matproj import MPRester

m = MPRester()
mpr = MPRester()
try:
criteria = json.loads(args.criteria)
except json.decoder.JSONDecodeError:
criteria = args.criteria
if args.structure:
count = 0
for d in m.query(criteria, properties=["structure", "task_id"]):
struct = d["structure"]
for dct in mpr.query(criteria, properties=["structure", "task_id"]):
struct = dct["structure"]
formula = re.sub(r"\s+", "", struct.formula)
if args.structure == "poscar":
fname = f"POSCAR.{d['task_id']}_{formula}"
fname = f"POSCAR.{dct['task_id']}_{formula}"
else:
fname = f"{d['task_id']}-{formula}.{args.structure}"
fname = f"{dct['task_id']}-{formula}.{args.structure}"
struct.to(filename=fname)
count += 1
print(f"{count} structures written!")
elif args.entries:
entries = m.get_entries(criteria)
entries = mpr.get_entries(criteria)
dumpfn(entries, args.entries)
print(f"{len(entries)} entries written to {args.entries}!")
else:
props = ["e_above_hull", "spacegroup"]
props += args.data
entries = m.get_entries(criteria, property_data=props)
t = []
entries = mpr.get_entries(criteria, property_data=props)
table = []
headers = ["mp-id", "Formula", "Spacegroup", "E/atom (eV)", "E above hull (eV)", *args.data]
for e in entries:
for entry in entries:
row = [
e.entry_id,
e.composition.reduced_formula,
e.data["spacegroup"]["symbol"],
e.energy_per_atom,
e.data["e_above_hull"],
entry.entry_id,
entry.composition.reduced_formula,
entry.data["spacegroup"]["symbol"],
entry.energy_per_atom,
entry.data["e_above_hull"],
]
row += [e.data[s] for s in args.data]
row += [entry.data[s] for s in args.data]

t.append(row)
table.append(row)

t = sorted(t, key=lambda x: x[headers.index("E above hull (eV)")])
print(tabulate(t, headers=headers, tablefmt="pipe", floatfmt=".3f"))
table = sorted(table, key=lambda x: x[headers.index("E above hull (eV)")])
print(tabulate(table, headers=headers, tablefmt="pipe", floatfmt=".3f"))
9 changes: 5 additions & 4 deletions pymatgen/io/vasp/inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,7 @@ def monkhorst_automatic(kpts: tuple[int, int, int] = (2, 2, 2), shift: Vector3D
def automatic_density(structure: Structure, kppa: float, force_gamma: bool = False):
"""
Returns an automatic Kpoint object based on a structure and a kpoint
density. Uses Gamma centered meshes for hexagonal cells and
density. Uses Gamma centered meshes for hexagonal cells and face-centered cells,
Monkhorst-Pack grids otherwise.

Algorithm:
Expand All @@ -1219,9 +1219,9 @@ def automatic_density(structure: Structure, kppa: float, force_gamma: bool = Fal
num_div = [int(math.floor(max(mult / length, 1))) for length in lengths]

is_hexagonal = latt.is_hexagonal()

is_face_centered = structure.get_space_group_info()[0][0] == "F"
has_odd = any(i % 2 == 1 for i in num_div)
if has_odd or is_hexagonal or force_gamma:
if has_odd or is_hexagonal or is_face_centered or force_gamma:
style = Kpoints.supported_modes.Gamma
else:
style = Kpoints.supported_modes.Monkhorst
Expand Down Expand Up @@ -1310,8 +1310,9 @@ def automatic_density_by_lengths(
abc = lattice.abc
num_div = [np.ceil(ld / abc[idx]) for idx, ld in enumerate(length_densities)]
is_hexagonal = lattice.is_hexagonal()
is_face_centered = structure.get_space_group_info()[0][0] == "F"
has_odd = any(idx % 2 == 1 for idx in num_div)
if has_odd or is_hexagonal or force_gamma:
if has_odd or is_hexagonal or is_face_centered or force_gamma:
style = Kpoints.supported_modes.Gamma
else:
style = Kpoints.supported_modes.Monkhorst
Expand Down
2 changes: 1 addition & 1 deletion pymatgen/symmetry/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def __init__(self, structure: Structure, symprec: float | None = 0.01, angle_tol
tuple(map(tuple, structure.lattice.matrix.tolist())),
tuple(map(tuple, structure.frac_coords.tolist())),
tuple(zs),
tuple(magmoms),
tuple(map(tuple, magmoms) if isinstance(magmoms[0], Sequence) else magmoms),
)
else: # if no magmoms given do not add to cell
self._cell = (
Expand Down
11 changes: 11 additions & 0 deletions tests/files/POSCAR_bcc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
H2
1.0
1.0000000000000000 0.0000000000000000 0.0000000000000000
0.0000000000000000 1.0000000000000000 0.0000000000000000
0.0000000000000000 0.0000000000000000 1.0000000000000000
H
2
direct
0.0000000000000000 0.0000000000000000 0.0000000000000000 H
0.5000000000000000 0.5000000000000000 0.5000000000000000 H

17 changes: 17 additions & 0 deletions tests/files/POSCAR_fcc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
H8
1.0
0.0000000000000000 1.0000000000000000 1.0000000000000000
1.0000000000000000 0.0000000000000000 1.0000000000000000
1.0000000000000000 1.0000000000000000 0.0000000000000000
H
8
direct
0.0000000000000000 0.0000000000000000 0.0000000000000000 H
0.0000000000000000 0.0000000000000000 0.5000000000000000 H
0.0000000000000000 0.5000000000000000 0.0000000000000000 H
0.0000000000000000 0.5000000000000000 0.5000000000000000 H
0.5000000000000000 0.0000000000000000 0.0000000000000000 H
0.5000000000000000 0.0000000000000000 0.5000000000000000 H
0.5000000000000000 0.5000000000000000 0.0000000000000000 H
0.5000000000000000 0.5000000000000000 0.5000000000000000 H

11 changes: 11 additions & 0 deletions tests/files/POSCAR_hcp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
H2
1.0
0.5000000000000000 -0.8660254037844390 0.0000000000000000
0.5000000000000000 0.8660254037844390 0.0000000000000000
0.0000000000000000 0.0000000000000000 1.6329931618554521
H
2
direct
0.0000000000000000 0.0000000000000000 0.0000000000000000 H
0.3333333333333330 -0.3333333333333330 0.5000000000000000 H

28 changes: 28 additions & 0 deletions tests/io/vasp/test_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,34 @@ def test_automatic_density_by_lengths(self):

assert kpoints.style == expected_style

def test_automatic_monkhorst_vs_gamma_style_selection(self):
structs = {key: Structure.from_file(f"{TEST_FILES_DIR}/POSCAR_{key}") for key in ("bcc", "fcc", "hcp")}

# bcc structures should allow both Monkhorst and Gamma
for struct_type, struct in structs.items():
for density in (500, 600, 700):
kpoints = Kpoints.automatic_density(struct, density)
if struct_type == "bcc" and density in (500, 600):
assert kpoints.style == Kpoints.supported_modes.Monkhorst
else:
assert kpoints.style == Kpoints.supported_modes.Gamma

# Kpoints.automatic_density_by_lengths
for struct_type, struct in structs.items():
for lengths in [50, 50, 50], [53, 53, 53], [56, 56, 56]:
kpoints = Kpoints.automatic_density_by_lengths(struct, lengths)
if struct_type == "bcc" and all(length % 2 == 0 for length in lengths):
assert kpoints.style == Kpoints.supported_modes.Monkhorst
else:
assert kpoints.style == Kpoints.supported_modes.Gamma

# Overkill test to make sure these methods always set the style to Gamma
for len_density in range(1, 50):
for struct_type, struct in structs.items():
if struct_type != "bcc":
kpoints = Kpoints.automatic_density_by_lengths(struct, [len_density] * 3)
assert kpoints.style == Kpoints.supported_modes.Gamma


class TestPotcarSingle:
_multiprocess_shared_ = True
Expand Down