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

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

# coding: utf-8 

# Copyright (c) Pymatgen Development Team. 

# Distributed under the terms of the MIT License. 

"""Wrappers for ABINIT main executables""" 

from __future__ import unicode_literals, division, print_function 

 

import os 

 

from monty.string import list_strings 

from six.moves import map, cStringIO 

 

import logging 

logger = logging.getLogger(__name__) 

 

__author__ = "Matteo Giantomassi" 

__copyright__ = "Copyright 2013, The Materials Project" 

__version__ = "0.1" 

__maintainer__ = "Matteo Giantomassi" 

__email__ = "gmatteo at gmail.com" 

__status__ = "Development" 

__date__ = "$Feb 21, 2013M$" 

 

__all__ = [ 

"Mrgscr", 

"Mrggkk", 

"Mrgddb", 

] 

 

 

class ExecError(Exception): 

"""Error class raised by :class:`ExecWrapper`""" 

 

 

class ExecWrapper(object): 

"""Base class that runs an executable in a subprocess.""" 

Error = ExecError 

 

def __init__(self, manager=None, executable=None, verbose=0): 

""" 

Args: 

manager: :class:`TaskManager` object responsible for the submission of the jobs. 

if manager is None, the default manager is used. 

executable: path to the executable. 

verbose: Verbosity level. 

""" 

from .tasks import TaskManager 

self.manager = manager if manager is not None else TaskManager.from_user_config() 

self.manager = self.manager.to_shell_manager(mpi_procs=1) 

 

self.executable = executable if executable is not None else self.name 

assert os.path.basename(self.executable) == self.name 

self.verbose = int(verbose) 

 

def __str__(self): 

return "%s" % self.executable 

 

@property 

def name(self): 

return self._name 

 

def execute(self, workdir, exec_args=None): 

# Try to execute binary without and with mpirun. 

try: 

return self._execute(workdir, with_mpirun=True, exec_args=exec_args) 

except self.Error: 

return self._execute(workdir, with_mpirun=False, exec_args=exec_args) 

 

def _execute(self, workdir, with_mpirun=False, exec_args=None): 

""" 

Execute the executable in a subprocess inside workdir. 

 

Some executables fail if we try to launch them with mpirun. 

Use with_mpirun=False to run the binary without it. 

""" 

qadapter = self.manager.qadapter 

if not with_mpirun: qadapter.name = None 

 

script = qadapter.get_script_str( 

job_name=self.name, 

launch_dir=workdir, 

executable=self.executable, 

qout_path="qout_file.path", 

qerr_path="qerr_file.path", 

stdin=self.stdin_fname, 

stdout=self.stdout_fname, 

stderr=self.stderr_fname, 

exec_args=exec_args 

) 

 

# Write the script. 

script_file = os.path.join(workdir, "run" + self.name + ".sh") 

with open(script_file, "w") as fh: 

fh.write(script) 

os.chmod(script_file, 0o740) 

 

qjob, process = qadapter.submit_to_queue(script_file) 

self.stdout_data, self.stderr_data = process.communicate() 

self.returncode = process.returncode 

#raise self.Error("%s returned %s\n cmd_str: %s" % (self, self.returncode, self.cmd_str)) 

 

return self.returncode 

 

 

class Mrgscr(ExecWrapper): 

_name = "mrgscr" 

 

def merge_qpoints(self, workdir, files_to_merge, out_prefix): 

""" 

Execute mrgscr inside directory `workdir` to merge `files_to_merge`. 

Produce new file with prefix `out_prefix` 

""" 

# We work with absolute paths. 

files_to_merge = [os.path.abspath(s) for s in list_strings(files_to_merge)] 

nfiles = len(files_to_merge) 

 

if self.verbose: 

print("Will merge %d files with output_prefix %s" % (nfiles, out_prefix)) 

for (i, f) in enumerate(files_to_merge): 

print(" [%d] %s" % (i, f)) 

 

if nfiles == 1: 

raise self.Error("merge_qpoints does not support nfiles == 1") 

 

self.stdin_fname, self.stdout_fname, self.stderr_fname = \ 

map(os.path.join, 3 * [workdir], ["mrgscr.stdin", "mrgscr.stdout", "mrgscr.stderr"]) 

 

inp = cStringIO() 

inp.write(str(nfiles) + "\n") # Number of files to merge. 

inp.write(out_prefix + "\n") # Prefix for the final output file: 

 

for filename in files_to_merge: 

inp.write(filename + "\n") # List with the files to merge. 

 

inp.write("1\n") # Option for merging q-points. 

 

self.stdin_data = [s for s in inp.getvalue()] 

 

with open(self.stdin_fname, "w") as fh: 

fh.writelines(self.stdin_data) 

 

self.execute(workdir) 

 

 

class Mrggkk(ExecWrapper): 

_name = "mrggkk" 

 

def merge(self, workdir, gswfk_file, dfpt_files, gkk_files, out_gkk, binascii=0): 

""" 

Merge GGK files, return the absolute path of the new database. 

 

Args: 

gswfk_file: Ground-state WFK filename 

dfpt_files: List of 1WFK files to merge. 

gkk_files: List of GKK files to merge. 

out_gkk: Name of the output GKK file 

binascii: Integer flat. 0 --> binary output, 1 --> ascii formatted output 

""" 

raise NotImplementedError("This method should be tested") 

#out_gkk = out_gkk if cwd is None else os.path.join(os.path.abspath(cwd), out_gkk) 

 

# We work with absolute paths. 

gswfk_file = absath(gswfk_file) 

dfpt_files = [os.path.abspath(s) for s in list_strings(dfpt_files)] 

gkk_files = [os.path.abspath(s) for s in list_strings(gkk_files)] 

 

print("Will merge %d 1WF files, %d GKK file in output %s" % 

(len(dfpt_nfiles), len_gkk_files, out_gkk)) 

 

if self.verbose: 

for i, f in enumerate(dfpt_files): print(" [%d] 1WF %s" % (i, f)) 

for i, f in enumerate(gkk_files): print(" [%d] GKK %s" % (i, f)) 

 

self.stdin_fname, self.stdout_fname, self.stderr_fname = \ 

map(os.path.join, 3 * [workdir], ["mrggkk.stdin", "mrggkk.stdout", "mrggkk.stderr"]) 

 

inp = cStringIO() 

inp.write(out_gkk + "\n") # Name of the output file 

inp.write(str(binascii) + "\n") # Integer flag: 0 --> binary output, 1 --> ascii formatted output 

inp.write(gswfk_file + "\n") # Name of the groud state wavefunction file WF 

 

#dims = len(dfpt_files, gkk_files, ?) 

dims = " ".join([str(d) for d in dims]) 

inp.write(dims + "\n") # Number of 1WF, of GKK files, and number of 1WF files in all the GKK files 

 

# Names of the 1WF files... 

for fname in dfpt_files: 

inp.write(fname + "\n") 

 

# Names of the GKK files... 

for fname in gkk_files: 

inp.write(fname + "\n") 

 

self.stdin_data = [s for s in inp.getvalue()] 

 

with open(self.stdin_fname, "w") as fh: 

fh.writelines(self.stdin_data) 

 

self.execute(workdir) 

 

return out_gkk 

 

 

class Mrgddb(ExecWrapper): 

_name = "mrgddb" 

 

def merge(self, workdir, ddb_files, out_ddb, description, delete_source_ddbs=True): 

"""Merge DDB file, return the absolute path of the new database in workdir.""" 

# We work with absolute paths. 

ddb_files = [os.path.abspath(s) for s in list_strings(ddb_files)] 

if not os.path.isabs(out_ddb): 

out_ddb = os.path.join(os.path.abspath(workdir), os.path.basename(out_ddb)) 

 

if self.verbose: 

print("Will merge %d files into output DDB %s" % (len(ddb_files), out_ddb)) 

for i, f in enumerate(ddb_files): 

print(" [%d] %s" % (i, f)) 

 

# Handle the case of a single file since mrgddb uses 1 to denote GS files! 

if len(ddb_files) == 1: 

with open(ddb_files[0], "r") as inh, open(out_ddb, "w") as out: 

for line in inh: 

out.write(line) 

return out_ddb 

 

self.stdin_fname, self.stdout_fname, self.stderr_fname = \ 

map(os.path.join, 3 * [os.path.abspath(workdir)], ["mrgddb.stdin", "mrgddb.stdout", "mrgddb.stderr"]) 

 

inp = cStringIO() 

inp.write(out_ddb + "\n") # Name of the output file. 

inp.write(str(description) + "\n") # Description. 

inp.write(str(len(ddb_files)) + "\n") # Number of input DDBs. 

 

# Names of the DDB files. 

for fname in ddb_files: 

inp.write(fname + "\n") 

 

self.stdin_data = [s for s in inp.getvalue()] 

 

with open(self.stdin_fname, "wt") as fh: 

fh.writelines(self.stdin_data) 

 

retcode = self.execute(workdir, exec_args=['--nostrict']) 

if retcode == 0 and delete_source_ddbs: 

# Remove ddb files. 

for f in ddb_files: 

try: 

os.remove(f) 

except IOError: 

pass 

 

return out_ddb