Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

185

186

187

188

189

190

191

192

193

194

# coding: utf-8 

# Copyright (c) Pymatgen Development Team. 

# Distributed under the terms of the MIT License. 

 

from __future__ import division, unicode_literals 

 

""" 

This module implements input and output processing from PWSCF. 

""" 

 

__author__ = "Shyue Ping Ong" 

__copyright__ = "Copyright 2012, The Materials Virtual Lab" 

__version__ = "0.1" 

__maintainer__ = "Shyue Ping Ong" 

__email__ = "ongsp@ucsd.edu" 

__date__ = "3/27/15" 

 

 

import six 

 

from monty.re import regrep 

from collections import defaultdict 

 

 

class PWInput(object): 

""" 

Base input file class. Right now, only supports no symmetry and is 

very basic. 

""" 

 

def __init__(self, structure, pseudo, control=None, system=None, 

electrons=None, ions=None, cell=None, kpoints_mode="automatic", 

kpoints_grid=(1, 1, 1),kpoints_shift=(0, 0, 0)): 

""" 

Initializes a PWSCF input file. 

 

Args: 

structure (Structure): Input structure 

pseudo (dict): A dict of the pseudopotentials to use. 

control (dict): Control parameters. Refer to official PWSCF doc 

on supported parameters. Default to {"calculation": "scf"} 

system (dict): System parameters. Refer to official PWSCF doc 

on supported parameters. Default to None, which means {}. 

electrons (dict): Electron parameters. Refer to official PWSCF doc 

on supported parameters. Default to None, which means {}. 

ions (dict): Ions parameters. Refer to official PWSCF doc 

on supported parameters. Default to None, which means {}. 

cell (dict): Cell parameters. Refer to official PWSCF doc 

on supported parameters. Default to None, which means {}. 

kpoints_mode (str): Kpoints generation mode. Default to automatic. 

kpoints_grid (sequence): The kpoint grid. Default to (1, 1, 1). 

kpoints_shift (sequence): The shift for the kpoints. Defaults to 

(0, 0, 0). 

""" 

self.structure = structure 

sections = {} 

sections["control"] = control or {"calculation": "scf"} 

sections["system"] = system or {} 

sections["electrons"] = electrons or {} 

sections["ions"] = ions or {} 

sections["cell"] = cell or {} 

for species in self.structure.composition.keys(): 

if species.symbol not in pseudo: 

raise PWInputError("Missing %s in pseudo specification!") 

self.pseudo = pseudo 

self.sections = sections 

self.kpoints_mode = kpoints_mode 

self.kpoints_grid = kpoints_grid 

self.kpoints_shift = kpoints_shift 

 

def __str__(self): 

out = [] 

def to_str(v): 

if isinstance(v, six.string_types): 

return "'%s'" % v 

return v 

for k1 in ["control", "system", "electrons", "ions", "cell"]: 

v1 = self.sections[k1] 

out.append("&%s" % k1.upper()) 

sub = [] 

for k2 in sorted(v1.keys()): 

sub.append(" %s = %s" % (k2, to_str(v1[k2]))) 

if k1 == "system": 

sub.append(" ibrav = 0") 

sub.append(" nat = %d" % len(self.structure)) 

sub.append(" ntyp = %d" % len(self.structure.composition)) 

sub.append("/") 

out.append(",\n".join(sub)) 

 

out.append("ATOMIC_SPECIES") 

for k, v in self.structure.composition.items(): 

out.append(" %s %.4f %s" % (k.symbol, k.atomic_mass, 

self.pseudo[k.symbol])) 

out.append("ATOMIC_POSITIONS crystal") 

for site in self.structure: 

out.append(" %s %.6f %.6f %.6f" % (site.specie.symbol, site.a, 

site.b, site.c)) 

out.append("K_POINTS %s" % self.kpoints_mode) 

kpt_str = ["%s" % i for i in self.kpoints_grid] 

kpt_str.extend(["%s" % i for i in self.kpoints_shift]) 

out.append(" %s" % " ".join(kpt_str)) 

out.append("CELL_PARAMETERS angstrom") 

for vec in self.structure.lattice.matrix: 

out.append(" %f %f %f" % (vec[0], vec[1], vec[2])) 

return "\n".join(out) 

 

def write_file(self, filename): 

""" 

Write the PWSCF input file. 

 

Args: 

filename (str): The string filename to output to. 

""" 

with open(filename, "w") as f: 

f.write(self.__str__()) 

 

 

class PWInputError(BaseException): 

pass 

 

 

class PWOutput(object): 

 

patterns = { 

"energies": "total energy\s+=\s+([\d\.\-]+)\sRy", 

"ecut": "kinetic\-energy cutoff\s+=\s+([\d\.\-]+)\s+Ry", 

"lattice_type": "bravais\-lattice index\s+=\s+(\d+)", 

"celldm1": "celldm\(1\)=\s+([\d\.]+)\s", 

"celldm2": "celldm\(2\)=\s+([\d\.]+)\s", 

"celldm3": "celldm\(3\)=\s+([\d\.]+)\s", 

"celldm4": "celldm\(4\)=\s+([\d\.]+)\s", 

"celldm5": "celldm\(5\)=\s+([\d\.]+)\s", 

"celldm6": "celldm\(6\)=\s+([\d\.]+)\s", 

"nkpts": "number of k points=\s+([\d]+)" 

} 

 

def __init__(self, filename): 

self.filename = filename 

self.data = defaultdict(list) 

self.read_pattern(PWOutput.patterns) 

for k, v in self.data.items(): 

if k == "energies": 

self.data[k] = [float(i[0][0]) for i in v] 

elif k in ["lattice_type", "nkpts"]: 

self.data[k] = int(v[0][0][0]) 

else: 

self.data[k] = float(v[0][0][0]) 

 

def read_pattern(self, patterns, reverse=False, 

terminate_on_match=False, postprocess=str): 

""" 

General pattern reading. Uses monty's regrep method. Takes the same 

arguments. 

 

Args: 

patterns (dict): A dict of patterns, e.g., 

{"energy": "energy\(sigma->0\)\s+=\s+([\d\-\.]+)"}. 

reverse (bool): Read files in reverse. Defaults to false. Useful for 

large files, esp OUTCARs, especially when used with 

terminate_on_match. 

terminate_on_match (bool): Whether to terminate when there is at 

least one match in each key in pattern. 

postprocess (callable): A post processing function to convert all 

matches. Defaults to str, i.e., no change. 

 

Renders accessible: 

Any attribute in patterns. For example, 

{"energy": "energy\(sigma->0\)\s+=\s+([\d\-\.]+)"} will set the 

value of self.data["energy"] = [[-1234], [-3453], ...], to the 

results from regex and postprocess. Note that the returned 

values are lists of lists, because you can grep multiple 

items on one line. 

""" 

matches = regrep(self.filename, patterns, reverse=reverse, 

terminate_on_match=terminate_on_match, 

postprocess=postprocess) 

self.data.update(matches) 

 

def get_celldm(self, i): 

return self.data["celldm%d" % i] 

 

@property 

def final_energy(self): 

return self.data["energies"][-1] 

 

@property 

def lattice_type(self): 

return self.data["lattice_type"] 

 

 

if __name__ == "__main__": 

o = PWOutput("../../test_files/Si.pwscf.out") 

print(o.data) 

print(o.final_energy)