1#!/usr/local/bin/python3.8
2
3# Script to create a gsphere.inp file automatically from a Quantum Espresso
4# data-file.xml file.
5#
6# For use with Visual/gsphere.py.
7#
8# On command line, specify:
9# (1) path to data-file.xml from espresso calculation
10# (2) desired name for gsphere.py input file
11# (3) g-sphere cutoff (in Ry)
12# (4, optional) logical for g-vector ordering (default is false)
13# (5, optional) k-point for use with g-sphere (default is origin)
14#
15# e.g., data-file2gsphere.py gsphere.inp --gcut 25
16#
17# Confirmed to work with Python version 2.7.9.
18# Incompatible with Python version 2.6.6.
19#
20# Bradford A. Barker (Sept, 2015), after FHJ data-file2kgrid.py
21
22import xml.etree.cElementTree as ET
23
24def create_gsphere_inp(datafile, f_gsphere, gcut, order_gvecs, kpoint):
25
26    tree = ET.parse(datafile)
27
28    a1 = tree.find('CELL/DIRECT_LATTICE_VECTORS/a1').text.strip()
29    a2 = tree.find('CELL/DIRECT_LATTICE_VECTORS/a2').text.strip()
30    a3 = tree.find('CELL/DIRECT_LATTICE_VECTORS/a3').text.strip()
31    f_gsphere.write(' {}\n'.format(a1))
32    f_gsphere.write(' {}\n'.format(a2))
33    f_gsphere.write(' {}\n'.format(a3))
34
35    f_gsphere.write(' {}\n'.format(gcut))
36
37    node = tree.find('PLANE_WAVES/FFT_GRID')
38    fftgrid  = [node.get(nr) for nr in ('nr1', 'nr2', 'nr3')]
39    f_gsphere.write('{} {} {}\n'.format(*fftgrid))
40
41    def write_bool(b):
42        if b:
43            f_gsphere.write('true\n')
44        else:
45            f_gsphere.write('false\n')
46
47    write_bool(order_gvecs)
48
49    f_gsphere.write((3*'{:.12f} '+'\n').format(*kpoint))
50
51
52if __name__=="__main__":
53    from argparse import ArgumentParser
54
55    desc = ('Creates a gsphere.inp file given a data-file.xml from a Quantum'
56    ' Espresso save directory.')
57    parser = ArgumentParser(description=desc)
58
59    group = parser.add_argument_group('required input and output files')
60    group.add_argument('datafile', help='input data-file.xml from a QE save directory')
61    group.add_argument('gsphere_inp', help='output kgrid.inp file to generate')
62
63    group = parser.add_argument_group('required value of gvector cutoff')
64    group.add_argument('--gcut', help='value of gvector cutoff (units of Ry)')
65
66    group = parser.add_argument_group('order gvectors (optional)')
67    group.add_argument('--order_gvecs', default=False, action='store_true',
68        help='Whether to order gvectors. Defaults to false.')
69
70    group = parser.add_argument_group('kpoint specification (optional)')
71    group.add_argument('--kpoint', type=float, default=[0.0,0.0,0.0], nargs=3,
72    metavar=('k1', 'k2', 'k3'),
73        help='k-point about which to calculate the G-sphere. Defaults to origin.')
74
75    args = parser.parse_args()
76
77    with open(args.gsphere_inp, 'w') as f_gsphere:
78        create_gsphere_inp(args.datafile, f_gsphere, args.gcut, args.order_gvecs, args.kpoint)
79