Source code for kpath

#!/usr/bin/env python
#"""Writen by Niraj K. Nepal, Ph.D."""
"""Module to handle kpath for high-symmetry lines"""
import os
import sys
from ase.io import espresso,vasp
import pylab
from pymatgen.io.vasp.inputs import Kpoints
from pymatgen.core import Structure
from pymatgen.symmetry.bandstructure import HighSymmKpath
from check_json import config

[docs] def kpath(filename,npoint,kcutoff): """ Function to write k-point mesh along the high-symmetry path of the Brillouin zone (BZ). Parameters: - filename (str): Input file to read, which contains the structure or VASP 'POSCAR' file. - npoint (int): Size of k-point mesh. - kcutoff (int): Cutoff to use for k-point path in ASE. '0' means full Brillouin zone, '1' means to remove one symmetry point from the BZ path. Returns: - kpoints (numpy.ndarray): K-mesh of size (npoint, 3). - sympoint (list): K-point in linear axis ready for plotting after processing. - symname (list): Naming for sympoint. - kpt (list): K-point in linear axis without processing. - spt (list): K-point in linear axis without processing at high-symmetry points. - sym (list): Naming for spt. Example: >>> kpoints, sympoint, symname, kpt, sym, spt = kpath("POSCAR", 100, 0) """ input_data = config() try: # Attempt to read the input file as an espresso file. file_name = espresso.read_espresso_in(filename) except: # If reading as an espresso file fails, try VASP file. file_name = vasp.read_vasp(filename) inp_dict = input_data['download']['inp'] if "kpath_pbc" in inp_dict.keys(): pbc = inp_dict['kpath_pbc'] else: pbc = [1, 1, 1] if pbc is None: pbc = [1, 1, 1] # Get the band path from the cell. bandpath = file_name.cell.bandpath(pbc=pbc) # Determine the path based on the provided cutoff. if kcutoff > 0: path=bandpath.path[:kcutoff] else: path=bandpath.path[:None] # Generate the band path with the specified number of points. bandpath = file_name.cell.bandpath(path,npoints=npoint,pbc=pbc) file_name.cell.bandpath().plot() pylab.savefig("BZ.pdf", format='pdf', bbox_inches='tight') # Retrieve k-points, linear axis, and symmetry names. kpoints = bandpath.kpts sympoint = bandpath.get_linear_kpoint_axis()[1] symname = bandpath.get_linear_kpoint_axis()[2] # Process the combined labels. sympoint2 = [] idx = [] for i in range(sympoint.shape[0]): # Check if the current point has the same position as the previous one. if sympoint[i-1] == sympoint[i]: # Append the previous label to the current point. symadd = symname[i-1] + "|" + symname[i] symname[i] = symadd # Store the index of the previous point to be removed. idx.append(i-1) else: sympoint2.append(round(sympoint[i],8)) # Remove the redundant labels from the list. rmv = len(idx) while rmv > 0: symname.pop(idx[rmv-1]) rmv = rmv - 1 sympoint = sympoint2 # Retrieve additional data. spt = bandpath.get_linear_kpoint_axis()[1] sym = bandpath.get_linear_kpoint_axis()[2] kpt = bandpath.get_linear_kpoint_axis()[0] return kpoints,sympoint,symname,kpt,sym,spt
[docs] def printk(): """ Print k-point mesh within high-symmetry points and between them. This function generates and prints k-points for quantum mechanics calculations, focusing on the Brillouin zone (BZ) and high-symmetry points. Parameters: None Returns: None Usage: The function expects command-line arguments in the following order: - sys.argv[2]: Filename containing the structure or VASP 'POSCAR' file. - sys.argv[3]: Number of k-points. - sys.argv[4]: Cutoff for the k-point path in ASE. '0' for the full Brillouin zone, '1' to remove one symmetry point from the BZ path. - sys.argv[5]: Weight of the k-point (optional). Output: The function generates two files in the 'scf_dir' directory: - 'kpathlines.dat': Contains the k-point mesh within high-symmetry points and between them. - 'kspecial-points.dat': Lists the high-symmetry points. """ filename = sys.argv[2] nkpoint = int(sys.argv[3]) kcutoff = int(sys.argv[4]) weight = int(sys.argv[5]) kpts,sympoint,symname,_,_,_ = kpath(filename,nkpoint,kcutoff) nkpt = kpts.shape[0] if not os.path.isdir("scf_dir"): os.system("mkdir scf_dir") with open('scf_dir/kpathlines.dat', 'w') as kpathlines: kpathlines.write('K_POINTS crystal\n') kpathlines.write(str(nkpt) + '\n') for i in range(nkpt): kpathlines.write(str(round(kpts[i][0],8)) + " " + str(round(kpts[i][1],8))) kpathlines.write(" " + str(round(kpts[i][2],8)) + " " + str(weight) + "\n") with open('scf_dir/kspecial-points.dat', 'w') as special_points: special_points.write(str(sympoint) + "\n") special_points.write(str(symname))
[docs] def make_line_kpt(filename="KPOINTS"): """ Function to create high symmetry points for line mode using pymatgen. This function generates high symmetry points for line mode using the provided structure file ("POSCAR"). The number of k-points for the line mode is specified by the second command-line argument. Parameters: None Returns: None Usage: The function expects a command-line argument specifying the number of k-points for line mode. Output: The function creates a KPOINTS file containing high symmetry points for line mode. """ input_data = config() inp_dict = input_data['download']['inp'] if "kpath_pbc" in inp_dict.keys(): pbc = inp_dict['kpath_pbc'] else: pbc = [1, 1, 1] if pbc is None: pbc = [1, 1, 1] nkpt=int(sys.argv[2]) if pbc == [1, 1, 1]: struct = Structure.from_file("POSCAR") k_path = HighSymmKpath(struct) kpts = Kpoints.automatic_linemode(divisions=nkpt,ibz=k_path) kpts.write_file(filename) else: data = vasp.read_vasp("POSCAR") bandpath = data.cell.bandpath(pbc=pbc) path = bandpath.path special_points = bandpath.special_points with open(filename, "w") as write_kpt: write_kpt.write("Line_mode KPOINTS file\n") write_kpt.write(str(nkpt) + "\n") write_kpt.write("Line_mode\n") write_kpt.write("Reciprocal\n") for i in range(len(path) - 1): xpath = path[i] ypath = path[i+1] array1 = special_points[xpath] array2 = special_points[ypath] write_kpt.write(str(array1[0]) + " " + str(array1[1]) + " " + str(array1[2]) + " ! " + xpath + "\n") write_kpt.write(str(array2[0]) + " " + str(array2[1]) + " " + str(array2[2]) + " ! " + ypath + "\n") write_kpt.write("\n") os.system(f"""sed -i '$d' {filename}""")
[docs] def main(): """ Main function for executing different modes of k-point generation. Parameters: None Returns: None """ input_data = config() mode = sys.argv[1] if mode == "line": if os.path.isfile("KPT_OPT"): make_line_kpt("KPOINTS_OPT") else: make_line_kpt() elif mode == "point": printk() else: print("Either line or point mode available\n")
if __name__ == "__main__": input_data = config() if "kpt_opt" in input_data.keys(): kpt_opt = input_data["kpt_opt"] else: kpt_opt = False if kpt_opt: os.system("touch KPT_OPT") main()