Skip to content

Instantly share code, notes, and snippets.

@galjos
Created November 10, 2023 13:09
Show Gist options
  • Save galjos/720283f047678b83037b2c76957a32c8 to your computer and use it in GitHub Desktop.
Save galjos/720283f047678b83037b2c76957a32c8 to your computer and use it in GitHub Desktop.
Uses pymatgen to produce a CRYSTAL bandstructure input file - deriving a continuous path from a CIF file.
#!/usr/bin/env python3
import sys
from pymatgen.core import Structure
from pymatgen.symmetry.bandstructure import HighSymmKpath
import networkx as nx
# ingore warnings
import warnings
warnings.filterwarnings("ignore")
# Check if input file is given
if len(sys.argv) != 2:
print("Usage: " + sys.argv[0] + " <cif-inputfile>")
sys.exit(1)
# Read input file
inputfile = sys.argv[1]
# Read structure from input file
struc = Structure.from_file(inputfile)
# Get high symmetry kpath
kplm = HighSymmKpath(struc)
# Get path
path_kpath = kplm.kpath['path']
# Get labels for path to feed into networkx
labels = []
for i, slist in enumerate(path_kpath):
for j, element in enumerate(path_kpath[i]):
if j == 0:
labels.append(element)
elif j == len(path_kpath[i]) - 1:
labels.append(element)
else:
labels.append(element)
labels.append(element)
# Create graph
G = nx.Graph()
# Add edges to graph
for i in range(int(len(labels) / 2)):
G.add_edges_from([(labels[2 * i], labels[(2 * i) + 1])])
# Eulerize graph and get euler circuit
G_euler = nx.algorithms.euler.eulerize(G)
G_euler_circuit = nx.algorithms.euler.eulerian_circuit(G_euler)
# Convert euler circuit to list
G_euler_circuit = list(G_euler_circuit)
# length of euler circuit for output in CRYSTAL.D3 format
length = len(G_euler_circuit)
# Get new labels for kpoints
new_labels = []
for edge in G_euler_circuit:
new_labels.append(edge[0])
new_labels.append(G_euler_circuit[-1][1])
k_vector = 12 # k-vector scaling factor
### OUPUT IN CRYSTAL.D3 FORMAT ###
print("BAND") # header
print(" - ".join(new_labels)) # labels
print(length, k_vector, 300, 1, 100, 1, 0)
kpoints = kplm.kpath['kpoints']
for edge in G_euler_circuit:
# print kpoints formatted
for kpoint in kpoints[edge[0]]:
print(round(kpoint*k_vector), end=" ")
print(end="")
for kpoint in kpoints[edge[1]]:
print(round(kpoint*k_vector), end=" ")
print('G' if edge[0] == '\Gamma' else edge[0], end=" ")
print('G' if edge[1] == '\Gamma' else edge[1])
print("END") # end of kpoints
print()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment