diff --git a/.ci_support/environment.yml b/.ci_support/environment.yml index f8a527766..4bea0da86 100644 --- a/.ci_support/environment.yml +++ b/.ci_support/environment.yml @@ -15,5 +15,6 @@ dependencies: - pyscal =2.10.18 - scikit-learn =1.3.0 - scipy =1.11.3 +- seekpath =2.1.0 - spglib =2.0.2 - sqsgenerator =0.3 diff --git a/setup.py b/setup.py index 1f03ffc0e..02c0443b5 100644 --- a/setup.py +++ b/setup.py @@ -44,7 +44,8 @@ "symmetry": ['spglib==2.1.0'], "surface": ['spglib==2.1.0', 'pymatgen==2023.9.10'], "phonopy": ['phonopy==2.20.0', 'spglib==2.1.0'], - "pyxtal": ['pyxtal==0.6.0'] + "pyxtal": ['pyxtal==0.6.0'], + "seekpath": ['seekpath==2.1.0'], }, cmdclass=versioneer.get_cmdclass(), ) diff --git a/structuretoolkit/analyse/__init__.py b/structuretoolkit/analyse/__init__.py index 34d4a8115..f972dcaa6 100644 --- a/structuretoolkit/analyse/__init__.py +++ b/structuretoolkit/analyse/__init__.py @@ -1,6 +1,7 @@ import numpy as np from structuretoolkit.analyse.distance import find_mic, get_distances_array +from structuretoolkit.analyse.line import create_line_mode_structure from structuretoolkit.analyse.neighbors import get_neighborhood, get_neighbors from structuretoolkit.analyse.phonopy import get_equivalent_atoms from structuretoolkit.analyse.pyscal import ( diff --git a/structuretoolkit/analyse/line.py b/structuretoolkit/analyse/line.py new file mode 100644 index 000000000..e504f81a2 --- /dev/null +++ b/structuretoolkit/analyse/line.py @@ -0,0 +1,55 @@ +from ase.atoms import Atoms + + +def create_line_mode_structure( + structure, + with_time_reversal=True, + recipe="hpkot", + threshold=1e-07, + symprec=1e-05, + angle_tolerance=-1.0, +): + """ + Uses 'seekpath' to create a new structure with high symmetry points and path for band structure calculations. + + Args: + with_time_reversal (bool): if False, and the group has no inversion symmetry, + additional lines are returned as described in the HPKOT paper. + recipe (str): choose the reference publication that defines the special points and paths. + Currently, only 'hpkot' is implemented. + threshold (float): the threshold to use to verify if we are in and edge case + (e.g., a tetragonal cell, but a==c). For instance, in the tI lattice, if abs(a-c) < threshold, + a EdgeCaseWarning is issued. Note that depending on the bravais lattice, + the meaning of the threshold is different (angle, length, …) + symprec (float): the symmetry precision used internally by SPGLIB + angle_tolerance (float): the angle_tolerance used internally by SPGLIB + + Returns: + pyiron.atomistics.structure.atoms.Atoms: new structure + """ + import seekpath + + input_structure = (structure.cell, structure.get_scaled_positions(), self.indices) + sp_dict = seekpath.get_path( + structure=input_structure, + with_time_reversal=with_time_reversal, + recipe=recipe, + threshold=threshold, + symprec=symprec, + angle_tolerance=angle_tolerance, + ) + + original_element_list = structure.get_chemical_symbols() + element_list = [original_element_list[l] for l in sp_dict["primitive_types"]] + positions = sp_dict["primitive_positions"] + pbc = structure.pbc + cell = sp_dict["primitive_lattice"] + + struc_new = Atoms( + elements=element_list, scaled_positions=positions, pbc=pbc, cell=cell + ) + + struc_new._set_high_symmetry_points(sp_dict["point_coords"]) + struc_new._set_high_symmetry_path({"full": sp_dict["path"]}) + + return struc_new