-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathphonopy-get-comm-pts
184 lines (130 loc) · 4.87 KB
/
phonopy-get-comm-pts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/usr/bin/env python
# -------
# Imports
# -------
from argparse import ArgumentParser
# These imports will fail if Phonopy is not installed, or perhaps if a (very) old version of Phonopy is installed.
# If this happens, intercept the ImportErrors with a clearer error message.
try:
from phonopy import Phonopy
from phonopy.harmonic.dynmat_to_fc import DynmatToForceConstants
from phonopy.interface.vasp import read_vasp
except ImportError:
raise Exception("Error: This script requires a recent version of Phonopy to be installed.")
# ---------
# Functions
# ---------
def ParseFracVal(val):
""" Parses fractional values entered as strings of the form 'X/Y'. """
if '/' in val:
# Assume val is a fraction.
num, denom = val.split('/')
return float(num) / float(denom)
else:
# Assume val is a float.
return float(val)
def ParseMatrix(mat_str):
"""
Attempt to parse and return a 3x3 matrix from mat_str.
mat_str may consist of either:
- the three diagonal values xx, yy and zz
- all nine elements xx, xy, xz, yx, yy, yz, zx, zy, zz
Elements are converted to floats using ParseFracVal() and may therefore be specified as fractions (e.g. 1/2).
"""
elements = [
ParseFracVal(val) for val in mat_str.split()
]
if len(elements) == 3:
xx, yy, zz = elements
return [
[xx, 0 , 0 ],
[0 , yy, 0 ],
[0 , 0 , zz]
]
elif len(elements) == 9:
xx, xy, xz, yx, yy, yz, zx, zy, zz = elements
return [
[xx, xy, xz],
[yx, yy, yz],
[zx, zy, zz]
]
else:
raise Exception("Error: Matrices must be specified as three diagonal elements or all nine elements.")
# ----
# Main
# ----
if __name__ == "__main__":
# Parse command-line arguments.
parser = ArgumentParser(
description = "List commensurate q-points for a given supercell expansion"
)
parser.add_argument(
"-c",
metavar = "poscar_file",
dest = "Structure", default="POSCAR",
help = "Crystal structure (must be a VASP POSCAR file; default: POSCAR)"
)
parser.add_argument(
"--dim",
metavar = "supercell_matrix",
dest = "SupercellMatrix", required = True,
help = "Supercell dimension (3 values) or matrix (9 values) - fractional values e.g. 1/2 accepted"
)
parser.add_argument(
"--pa", "--primitive_axis",
metavar = "primitive_matrix",
dest = "PrimitiveMatrix",
help = "Transformation matrix to a primitive cell"
)
parser.add_argument(
"--qpoints",
dest = "WriteQPOINTS", action = 'store_true',
help = "Write commensurate points to a Phonopy QPOINTS file"
)
args = parser.parse_args()
# Parse primitive and supercell matrices.
supercell_matrix = ParseMatrix(args.SupercellMatrix)
primitive_matrix = None
if args.PrimitiveMatrix is not None:
primitive_matrix = ParseMatrix(args.PrimitiveMatrix)
# Read structure.
structure = read_vasp(args.Structure)
# Construct a Phonopy object.
phonon = Phonopy(
structure, supercell_matrix,
primitive_matrix = primitive_matrix
)
# Construct a DynmatToForceConstants object and get commensurate points.
dynmat_to_fc = DynmatToForceConstants(
phonon.get_primitive(),
phonon.get_supercell()
)
comm_pts = dynmat_to_fc.commensurate_points
# Print input parameters and list commensurate points.
print("Strucure: {0}".format(args.Structure))
print("")
if primitive_matrix is not None:
print("Primitive Matrix")
print("----------------")
for row in primitive_matrix:
print("[ {0: >6.3f} {1: >6.3f} {2: >6.3f} ]".format(*row))
print("")
print("Supercell Matrix")
print("----------------")
for row in supercell_matrix:
print("[ {0: >6.3f} {1: >6.3f} {2: >6.3f} ]".format(*row))
print("")
print("Commensurate Points")
print("-------------------")
for i, (q_x, q_y, q_z) in enumerate(comm_pts):
print("{0: >4} : {1: >6.3f} {2: >6.3f} {3: >6.3f}".format(i + 1, q_x, q_y, q_z))
# If requested, write commensurate points to a Phonopy QPOINTS file.
if args.WriteQPOINTS:
with open(r"QPOINTS", 'w') as output_writer:
output_writer.write(
"{0}\n".format(len(comm_pts))
)
for q_x, q_y, q_z in comm_pts:
output_writer.write(
"{0: >18.15f} {1: >18.15f} {2: >18.15f}\n".format(q_x, q_y, q_z)
)