diff --git a/seekpath/getpaths.py b/seekpath/getpaths.py index 2f1d4c5..f9a8ebc 100644 --- a/seekpath/getpaths.py +++ b/seekpath/getpaths.py @@ -166,9 +166,10 @@ def get_path( (the determinant is integer and gives the ratio in volume between the conventional and primitive cells) - ``volume_original_wrt_conv``: volume ratio of the user-provided cell - with respect to the the crystallographic conventional cell + with respect to the crystallographic conventional cell - ``volume_original_wrt_prim``: volume ratio of the user-provided cell - with respect to the the crystalloraphic primitive cell + with respect to the crystallographic primitive cell (both volume + ratios are negative if the user-provided cell is left-handed) :note: An :py:exc:`~seekpath.hpkot.EdgeCaseWarning` is issued for edge cases (e.g. if ``a==b==c`` for @@ -421,7 +422,9 @@ def get_path_orig_cell( recipe=recipe, ) - is_supercell = abs(res['volume_original_wrt_prim'] - 1) > 0.1 + # The volume ratio is negative for a left-handed input cell, so only its + # magnitude says whether the cell is a supercell + is_supercell = abs(abs(res['volume_original_wrt_prim']) - 1) > 0.1 if is_supercell: warnings.warn( diff --git a/seekpath/hpkot/__init__.py b/seekpath/hpkot/__init__.py index 708d393..e6930c2 100644 --- a/seekpath/hpkot/__init__.py +++ b/seekpath/hpkot/__init__.py @@ -119,9 +119,10 @@ def get_path( - ``rotation_matrix``: rotation matrix in Cartesian space from the input cell to the standardized cell - ``volume_original_wrt_conv``: volume ratio of the user-provided cell - with respect to the the crystallographic conventional cell + with respect to the crystallographic conventional cell - ``volume_original_wrt_prim``: volume ratio of the user-provided cell - with respect to the the crystallographic primitive cell + with respect to the crystallographic primitive cell (both volume + ratios are negative if the user-provided cell is left-handed) :note: An :py:exc:`~seekpath.hpkot.EdgeCaseWarning` is issued for edge cases (e.g. if ``a==b==c`` for diff --git a/tests/test_brillouinzone.py b/tests/test_brillouinzone.py index 89981dd..7af34d5 100644 --- a/tests/test_brillouinzone.py +++ b/tests/test_brillouinzone.py @@ -24,7 +24,7 @@ def is_same_face(f1, f2): f1 and f2 should be a list of 3d points (i.e., a list of lists). - It also checks if the the coordinates are shifted (i.e. the first one is + It also checks if the coordinates are shifted (i.e. the first one is now the second, the second the third etc.). Tries also points in reversed order. """ diff --git a/tests/test_paths_hpkot.py b/tests/test_paths_hpkot.py index 508d720..77f7463 100644 --- a/tests/test_paths_hpkot.py +++ b/tests/test_paths_hpkot.py @@ -1002,6 +1002,38 @@ def test_nonstandard_cubic_supercell(self): self.assertEqual(res['spacegroup_international'], 'Pm-3m') + def test_left_handed_fcc(self): + """ + Obtain the k-path for a left-handed primitive fcc cell, which is not + a supercell even though its volume ratio to the primitive cell is -1. + """ + import warnings + + from seekpath import SupercellWarning + + cell = [[-3.0, 0.0, 3.0], [0.0, 3.0, 3.0], [-3.0, 3.0, 0.0]] + positions = [[0.0, 0.0, 0.0], [0.25, 0.25, 0.25]] + atomic_numbers = [1, 1] + + # An improper rotation makes the cell left-handed + s = np.sin(0.3) + c = np.cos(0.3) + R = np.array([[-1.0, 0.0, 0.0], [0.0, c, s], [0.0, -s, c]]) + + cell = cell @ R + system = (cell, positions, atomic_numbers) + self.assertLess(np.linalg.det(cell), 0) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + res = self.base_test(system) + self.assertEqual(res['is_supercell'], False) + + relevant_w = [_ for _ in w if issubclass(_.category, SupercellWarning)] + self.assertEqual(relevant_w, []) + + self.assertEqual(res['spacegroup_international'], 'Fd-3m') + def test_no_symmetrization(self): """ Test that symmetrization is not performed so that the k path is on @@ -1089,22 +1121,16 @@ def test_path(self): # pylint: disable=no-self-use res_standard = seekpath.get_explicit_k_path(system, recipe='hpkot') with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') res_original = seekpath.get_explicit_k_path_orig_cell( system, recipe='hpkot' ) - self.assertEqual(res_original['is_supercell'], True) + # The cell is left-handed (because of the improper rotation R), but + # it is a primitive cell, not a supercell + self.assertEqual(res_original['is_supercell'], False) - # Checks on issued warnings relevant_w = [_ for _ in w if issubclass(_.category, SupercellWarning)] - self.assertEqual( - len(relevant_w), - 1, - f'Wrong number of warnings issued! ({len(relevant_w)} instead of 1)', - ) - - check_string = 'The provided cell is a supercell: the returned' - if check_string is not None: - self.assertIn(check_string, str(relevant_w[0].message)) + self.assertEqual(relevant_w, []) self.assertEqual(res_original['path'], res_standard['path']) self.assertEqual(res_original['augmented_path'], res_standard['augmented_path'])