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

Raise ValueError in SpacegroupAnalyzer.get_symmetrized_structure() if spglib returns no symmetries #2724

Merged
merged 5 commits into from
Nov 7, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ repos:
additional_dependencies: [flake8-bugbear]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.981
rev: v0.982
hooks:
- id: mypy

Expand Down
41 changes: 26 additions & 15 deletions pymatgen/io/lobster/inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
import itertools
import os
import warnings
from typing import Any, Dict, List, Sequence
from typing import Any, Sequence

import numpy as np
import spglib
from monty.io import zopen
from monty.json import MSONable
from monty.serialization import loadfn

from pymatgen.core.composition import Composition
from pymatgen.core.structure import Structure
from pymatgen.io.vasp import Vasprun
from pymatgen.io.vasp.inputs import Incar, Kpoints, Potcar
Expand All @@ -27,7 +28,7 @@
__author__ = "Janine George, Marco Esters"
__copyright__ = "Copyright 2017, The Materials Project"
__version__ = "0.2"
__maintainer__ = "Janine George, Marco Esters "
__maintainer__ = "Janine George, Marco Esters"
__email__ = "janine.george@uclouvain.be, esters@uoregon.edu"
__date__ = "Dec 13, 2017"

Expand Down Expand Up @@ -135,7 +136,7 @@ def __setitem__(self, key, val):

def __getitem__(self, item):
"""
implements getitem from dict to avoid problems with cases
Implements getitem from dict to avoid problems with cases
"""
found = False
for key_here in self:
Expand All @@ -152,8 +153,10 @@ def diff(self, other):
"""
Diff function for lobsterin. Compares two lobsterin and indicates which parameters are the same.
Similar to the diff in INCAR.

Args:
other (Lobsterin): Lobsterin object to compare to

Returns:
dict with differences and similarities
"""
Expand Down Expand Up @@ -209,12 +212,12 @@ def diff(self, other):

def _get_nbands(self, structure: Structure):
"""
get number of nbands
Get number of bands.
"""
if self.get("basisfunctions") is None:
raise OSError("No basis functions are provided. The program cannot calculate nbands.")

basis_functions = [] # type: List[str]
basis_functions: list[str] = []
for string_basis in self["basisfunctions"]:
# string_basis.lstrip()
string_basis_raw = string_basis.strip().split(" ")
Expand All @@ -238,7 +241,8 @@ def _get_nbands(self, structure: Structure):

def write_lobsterin(self, path="lobsterin", overwritedict=None):
"""
writes a lobsterin file
Writes a lobsterin file

Args:
path (str): filename of the lobsterin file that will be written
overwritedict (dict): dict that can be used to overwrite lobsterin, e.g. {"skipdos": True}
Expand Down Expand Up @@ -302,6 +306,7 @@ def write_INCAR(
"""
Will only make the run static, insert nbands, make ISYM=-1, set LWAVE=True and write a new INCAR.
You have to check for the rest.

Args:
incar_input (str): path to input INCAR
incar_output (str): path to output INCAR
Expand Down Expand Up @@ -335,11 +340,13 @@ def get_basis(
address_basis_file: str = None,
):
"""
will get the basis from given potcar_symbols (e.g., ["Fe_pv","Si"]
Will get the basis from given potcar_symbols (e.g., ["Fe_pv","Si"]
#include this in lobsterin class

Args:
structure (Structure): Structure object
potcar_symbols: list of potcar symbols

Returns:
returns basis
"""
Expand Down Expand Up @@ -415,7 +422,8 @@ def write_POSCAR_with_standard_primitive(
POSCAR_input="POSCAR", POSCAR_output="POSCAR.lobster", symprec: float = 0.01
):
"""
writes a POSCAR with the standard primitive cell. This is needed to arrive at the correct kpath
Writes a POSCAR with the standard primitive cell. This is needed to arrive at the correct kpath

Args:
POSCAR_input (str): filename of input POSCAR
POSCAR_output (str): filename of output POSCAR
Expand All @@ -439,7 +447,8 @@ def write_KPOINTS(
symprec: float = 0.01,
):
"""
writes a KPOINT file for lobster (only ISYM=-1 and ISYM=0 are possible), grids are gamma centered
Writes a KPOINT file for lobster (only ISYM=-1 and ISYM=0 are possible), grids are gamma centered

Args:
POSCAR_input (str): path to POSCAR
KPOINTS_output (str): path to output KPOINTS
Expand All @@ -463,7 +472,7 @@ def write_KPOINTS(
# we need to switch off symmetry here
latt = structure.lattice.matrix
positions = structure.frac_coords
unique_species = [] # type: List[Any]
unique_species: list[Composition] = []
zs = []
magmoms = []

Expand Down Expand Up @@ -572,7 +581,7 @@ def from_file(cls, lobsterin: str):
data = f.read().split("\n")
if len(data) == 0:
raise OSError("lobsterin file contains no data.")
Lobsterindict = {} # type: Dict
Lobsterindict: dict[str, Any] = {}

for datum in data:
# will remove all comments to avoid complications
Expand Down Expand Up @@ -608,9 +617,11 @@ def from_file(cls, lobsterin: str):
@staticmethod
def _get_potcar_symbols(POTCAR_input: str) -> list:
"""
will return the name of the species in the POTCAR
Will return the name of the species in the POTCAR

Args:
POTCAR_input(str): string to potcar file
POTCAR_input(str): string to potcar file

Returns:
list of the names of the species in string format
"""
Expand Down Expand Up @@ -650,7 +661,7 @@ def standard_calculations_from_vasp_files(
option: str = "standard",
):
"""
will generate Lobsterin with standard settings
Will generate Lobsterin with standard settings

Args:
POSCAR_input(str): path to POSCAR
Expand Down Expand Up @@ -694,7 +705,7 @@ def standard_calculations_from_vasp_files(
]:
raise ValueError("The option is not valid!")

Lobsterindict = {} # type: Dict[Any,Any]
Lobsterindict: dict[str, Any] = {}
# this basis set covers most elements
Lobsterindict["basisSet"] = "pbeVaspFit2015"
# energies around e-fermi
Expand Down
5 changes: 5 additions & 0 deletions pymatgen/symmetry/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ def _get_symmetry(self):
vectors in scaled positions.
"""
d = spglib.get_symmetry(self._cell, symprec=self._symprec, angle_tolerance=self._angle_tol)
if d is None:
raise ValueError(
f"Symmetry detection failed for structure with formula {self._structure.formula}. "
f"Try setting symprec={self._symprec} to a different value."
)
# Sometimes spglib returns small translation vectors, e.g.
# [1e-4, 2e-4, 1e-4]
# (these are in fractional coordinates, so should be small denominator
Expand Down
12 changes: 12 additions & 0 deletions pymatgen/symmetry/tests/test_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,18 @@ def test_get_symmetry_dataset(self):
ds = self.sg.get_symmetry_dataset()
assert ds["international"] == "Pnma"

def test_get_symmetry(self):
# see discussion in https://github.com/materialsproject/pymatgen/pull/2724
Co8 = Structure.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "Co8.cif"))
symprec = 1e-1

with pytest.raises(
ValueError,
match=f"Symmetry detection failed for structure with formula {Co8.formula}. "
f"Try setting {symprec=} to a different value.",
):
SpacegroupAnalyzer(Co8, symprec=symprec)._get_symmetry()

def test_get_crystal_system(self):
crystal_system = self.sg.get_crystal_system()
assert "orthorhombic" == crystal_system
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
"coveralls",
"doc2dash",
"flake8",
"mypy",
"mypy==0.982",
"pre-commit",
"pydocstyle",
"pylint",
Expand Down
34 changes: 34 additions & 0 deletions test_files/Co8.cif
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# generated using pymatgen
data_Co
_symmetry_space_group_name_H-M 'P 1'
_cell_length_a 3.70701825
_cell_length_b 3.70701825
_cell_length_c 7.98790154
_cell_angle_alpha 103.38852320
_cell_angle_beta 103.38852320
_cell_angle_gamma 89.96878549
_symmetry_Int_Tables_number 1
_chemical_formula_structural Co
_chemical_formula_sum Co8
_cell_volume 103.72064306
_cell_formula_units_Z 8
loop_
_symmetry_equiv_pos_site_id
_symmetry_equiv_pos_as_xyz
1 'x, y, z'
loop_
_atom_site_type_symbol
_atom_site_label
_atom_site_symmetry_multiplicity
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
_atom_site_occupancy
Co Co0 1 0.62683200 0.62683200 0.25354400 1.0
Co Co1 1 0.37316800 0.37316800 0.74645600 1.0
Co Co2 1 0.50000000 0.00000000 0.00000000 1.0
Co Co3 1 0.00000000 0.50000000 0.00000000 1.0
Co Co4 1 0.74993500 0.25006500 0.50000000 1.0
Co Co5 1 0.25006500 0.74993500 0.50000000 1.0
Co Co6 1 0.87978400 0.87978400 0.75931100 1.0
Co Co7 1 0.12021600 0.12021600 0.24068900 1.0