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# Copyright (C) 2008 CSC - Scientific Computing Ltd. 

2"""This module defines an ASE interface to VASP. 

3 

4Developed on the basis of modules by Jussi Enkovaara and John 

5Kitchin. The path of the directory containing the pseudopotential 

6directories (potpaw,potpaw_GGA, potpaw_PBE, ...) should be set 

7by the environmental flag $VASP_PP_PATH. 

8 

9The user should also set the environmental flag $VASP_SCRIPT pointing 

10to a python script looking something like:: 

11 

12 import os 

13 exitcode = os.system('vasp') 

14 

15Alternatively, user can set the environmental flag $VASP_COMMAND pointing 

16to the command use the launch vasp e.g. 'vasp' or 'mpirun -n 16 vasp' 

17 

18http://cms.mpi.univie.ac.at/vasp/ 

19""" 

20 

21import os 

22import warnings 

23import shutil 

24from os.path import join, isfile, islink 

25from typing import List, Sequence, Tuple 

26 

27import numpy as np 

28 

29import ase 

30from ase.calculators.calculator import kpts2ndarray 

31from ase.calculators.vasp.setups import get_default_setups 

32 

33# Parameters that can be set in INCAR. The values which are None 

34# are not written and default parameters of VASP are used for them. 

35 

36float_keys = [ 

37 'aexx', # Fraction of exact/DFT exchange 

38 'aggac', # Fraction of gradient correction to correlation 

39 'aggax', # Fraction of gradient correction to exchange 

40 'aldac', # Fraction of LDA correlation energy 

41 'amin', # 

42 'amix', # 

43 'amix_mag', # 

44 'bmix', # tags for mixing 

45 'bmix_mag', # 

46 'cshift', # Complex shift for dielectric tensor calculation (LOPTICS) 

47 'deper', # relative stopping criterion for optimization of eigenvalue 

48 'ebreak', # absolute stopping criterion for optimization of eigenvalues 

49 # (EDIFF/N-BANDS/4) 

50 'efield', # applied electrostatic field 

51 'emax', # energy-range for DOSCAR file 

52 'emin', # 

53 'enaug', # Density cutoff 

54 'encut', # Planewave cutoff 

55 'encutgw', # energy cutoff for response function 

56 'encutfock', # FFT grid in the HF related routines 

57 'hfscreen', # attribute to change from PBE0 to HSE 

58 'kspacing', # determines the number of k-points if the KPOINTS 

59 # file is not present. KSPACING is the smallest 

60 # allowed spacing between k-points in units of 

61 # $\AA$^{-1}$. 

62 'potim', # time-step for ion-motion (fs) 

63 'nelect', # total number of electrons 

64 'param1', # Exchange parameter 

65 'param2', # Exchange parameter 

66 'pomass', # mass of ions in am 

67 'pstress', # add this stress to the stress tensor, and energy E = V * 

68 # pstress 

69 'sigma', # broadening in eV 

70 'smass', # Nose mass-parameter (am) 

71 'spring', # spring constant for NEB 

72 'time', # special control tag 

73 'weimin', # maximum weight for a band to be considered empty 

74 'zab_vdw', # vdW-DF parameter 

75 'zval', # ionic valence 

76 # The next keywords pertain to the VTST add-ons from Graeme Henkelman's 

77 # group at UT Austin 

78 'jacobian', # Weight of lattice to atomic motion 

79 'ddr', # (DdR) dimer separation 

80 'drotmax', # (DRotMax) number of rotation steps per translation step 

81 'dfnmin', # (DFNMin) rotational force below which dimer is not rotated 

82 'dfnmax', # (DFNMax) rotational force below which dimer rotation stops 

83 'sltol', # convergence ratio for minimum eigenvalue 

84 'sdr', # finite difference for setting up Lanczos matrix and step 

85 # size when translating 

86 'maxmove', # Max step for translation for IOPT > 0 

87 'invcurv', # Initial curvature for LBFGS (IOPT = 1) 

88 'timestep', # Dynamical timestep for IOPT = 3 and IOPT = 7 

89 'sdalpha', # Ratio between force and step size for IOPT = 4 

90 # The next keywords pertain to IOPT = 7 (i.e. FIRE) 

91 'ftimemax', # Max time step 

92 'ftimedec', # Factor to dec. dt 

93 'ftimeinc', # Factor to inc. dt 

94 'falpha', # Parameter for velocity damping 

95 'falphadec', # Factor to dec. alpha 

96 'clz', # electron count for core level shift 

97 'vdw_radius', # Cutoff radius for Grimme's DFT-D2 and DFT-D3 and 

98 # Tkatchenko and Scheffler's DFT-TS dispersion corrections 

99 'vdw_scaling', # Global scaling parameter for Grimme's DFT-D2 dispersion 

100 # correction 

101 'vdw_d', # Global damping parameter for Grimme's DFT-D2 and Tkatchenko 

102 # and Scheffler's DFT-TS dispersion corrections 

103 'vdw_cnradius', # Cutoff radius for calculating coordination number in 

104 # Grimme's DFT-D3 dispersion correction 

105 'vdw_s6', # Damping parameter for Grimme's DFT-D2 and DFT-D3 and 

106 # Tkatchenko and Scheffler's DFT-TS dispersion corrections 

107 'vdw_s8', # Damping parameter for Grimme's DFT-D3 dispersion correction 

108 'vdw_sr', # Scaling parameter for Grimme's DFT-D2 and DFT-D3 and 

109 # Tkatchenko and Scheffler's DFT-TS dispersion correction 

110 'vdw_a1', # Damping parameter for Grimme's DFT-D3 dispersion correction 

111 'vdw_a2', # Damping parameter for Grimme's DFT-D3 dispersion correction 

112 'eb_k', # solvent permitivity in Vaspsol 

113 'tau', # surface tension parameter in Vaspsol 

114 'langevin_gamma_l', # Friction for lattice degrees of freedom 

115 'pmass', # Mass for latice degrees of freedom 

116 'bparam', # B parameter for nonlocal VV10 vdW functional 

117 'cparam', # C parameter for nonlocal VV10 vdW functional 

118 'aldax', # Fraction of LDA exchange (for hybrid calculations) 

119 'tebeg', # 

120 'teend', # temperature during run 

121 'andersen_prob', # Probability of collision in Andersen thermostat 

122 'apaco', # Distance cutoff for pair correlation function calc. 

123 'auger_ecblo', # Undocumented parameter for Auger calculations 

124 'auger_edens', # Density of electrons in conduction band 

125 'auger_hdens', # Density of holes in valence band 

126 'auger_efermi', # Fixed Fermi level for Auger calculations 

127 'auger_evbhi', # Upper bound for valence band maximum 

128 'auger_ewidth', # Half-width of energy window function 

129 'auger_occ_fac_eeh', # Undocumented parameter for Auger calculations 

130 'auger_occ_fac_ehh', # Undocumented parameter for Auger calculations 

131 'auger_temp', # Temperature for Auger calculation 

132 'dq', # Finite difference displacement magnitude (NMR) 

133 'avgap', # Average gap (Model GW) 

134 'ch_sigma', # Broadening of the core electron absorption spectrum 

135 'bpotim', # Undocumented Bond-Boost parameter (GH patches) 

136 'qrr', # Undocumented Bond-Boost parameter (GH patches) 

137 'prr', # Undocumented Bond-Boost parameter (GH patches) 

138 'rcut', # Undocumented Bond-Boost parameter (GH patches) 

139 'dvmax', # Undocumented Bond-Boost parameter (GH patches) 

140 'bfgsinvcurv', # Initial curvature for BFGS (GH patches) 

141 'damping', # Damping parameter for LBFGS (GH patches) 

142 'efirst', # Energy of first NEB image (GH patches) 

143 'elast', # Energy of final NEB image (GH patches) 

144 'fmagval', # Force magnitude convergence criterion (GH patches) 

145 'cmbj', # Modified Becke-Johnson MetaGGA c-parameter 

146 'cmbja', # Modified Becke-Johnson MetaGGA alpha-parameter 

147 'cmbjb', # Modified Becke-Johnson MetaGGA beta-parameter 

148 'sigma_nc_k', # Width of ion gaussians (VASPsol) 

149 'sigma_k', # Width of dielectric cavidty (VASPsol) 

150 'nc_k', # Cavity turn-on density (VASPsol) 

151 'lambda_d_k', # Debye screening length (VASPsol) 

152 'ediffsol', # Tolerance for solvation convergence (VASPsol) 

153 'deg_threshold', # Degeneracy threshold 

154 'omegamin', # Minimum frequency for dense freq. grid 

155 'omegamax', # Maximum frequency for dense freq. grid 

156 'rtime', # Undocumented parameter 

157 'wplasma', # Undocumented parameter 

158 'wplasmai', # Undocumented parameter 

159 'dfield', # Undocumented parameter 

160 'omegatl', # Maximum frequency for coarse freq. grid 

161 'encutgwsoft', # Soft energy cutoff for response kernel 

162 'encutlf', # Undocumented parameter 

163 'scissor', # Scissor correction for GW/BSE calcs 

164 'dimer_dist', # Distance between dimer images 

165 'step_size', # Step size for finite difference in dimer calculation 

166 'step_max', # Maximum step size for dimer calculation 

167 'minrot', # Minimum rotation allowed in dimer calculation 

168 'dummy_mass', # Mass of dummy atom(s?) 

169 'shaketol', # Tolerance for SHAKE algorithm 

170 'shaketolsoft', # Soft tolerance for SHAKE algorithm 

171 'shakesca', # Scaling of each step taken in SHAKE algorithm 

172 'hills_stride', # Undocumented metadynamics parameter 

173 'hills_h', # Height (in eV) of gaussian bias for metadynamics 

174 'hills_w', # Width of gaussian bias for metadynamics 

175 'hills_k', # Force constant coupling dummy&real for metadynamics 

176 'hills_m', # Mass of dummy particle for use in metadynamics 

177 'hills_temperature', # Temp. of dummy particle for metadynamics 

178 'hills_andersen_prob', # Probability of thermostat coll. for metadynamics 

179 'hills_sqq', # Nose-hoover particle mass for metadynamics 

180 'dvvdelta0', # Undocumented parameter 

181 'dvvvnorm0', # Undocumented parameter 

182 'dvvminpotim', # Undocumented parameter 

183 'dvvmaxpotim', # Undocumented parameter 

184 'efermi', # Undocumented parameter 

185 'enchg', # Undocumented charge fitting parameter 

186 'tau0', # Undocumented charge fitting parameter 

187 'encut4o', # Cutoff energy for 4-center integrals (HF) 

188 'param3', # Undocumented HF parameter 

189 'model_eps0', # Undocumented HF parameter 

190 'model_alpha', # Undocumented HF parameter 

191 'qmaxfockae', # Undocumented HF parameter 

192 'hfscreenc', # Range-separated screening length for correlations 

193 'hfrcut', # Cutoff radius for HF potential kernel 

194 'encutae', # Undocumented parameter for all-electron density calc. 

195 'encutsubrotscf', # Undocumented subspace rotation SCF parameter 

196 'enini', # Cutoff energy for wavefunctions (?) 

197 'wc', # Undocumented mixing parameter 

198 'enmax', # Cutoff energy for wavefunctions (?) 

199 'scalee', # Undocumented parameter 

200 'eref', # Reference energy 

201 'epsilon', # Dielectric constant of bulk charged cells 

202 'rcmix', # Mixing parameter for core density in rel. core calcs. 

203 'esemicore', # Energetic lower bound for states considered "semicore" 

204 'external_pressure', # Pressure for NPT calcs., equivalent to PSTRESS 

205 'lj_radius', # Undocumented classical vdW parameter 

206 'lj_epsilon', # Undocumented classical vdW parameter 

207 'lj_sigma', # Undocumented classical vdW parameter 

208 'mbd_beta', # TS MBD vdW correction damping parameter 

209 'scsrad', # Cutoff radius for dipole-dipole interaction tensor in SCS 

210 'hitoler', # Iterative Hirschfeld partitioning tolerance 

211 'lambda', # "Spring constant" for magmom constraint calcs. 

212 'kproj_threshold', # Threshold for k-point projection scheme 

213 'maxpwamp', # Undocumented HF parameter 

214 'vcutoff', # Undocumented parameter 

215 'mdtemp', # Temperature for AIMD 

216 'mdgamma', # Undocumented AIMD parameter 

217 'mdalpha', # Undocumented AIMD parameter 

218 'ofield_kappa', # Bias potential strength for interface pinning method 

219 'ofield_q6_near', # Steinhardt-Nelson Q6 parameters for interface pinning 

220 'ofield_q6_far', # Steinhardt-Nelson Q6 parameters for interface pinning 

221 'ofield_a', # Target order parameter for interface pinning method 

222 'pthreshold', # Don't print timings for routines faster than this value 

223 'qltol', # Eigenvalue tolerance for Lanczos iteration (instanton) 

224 'qdr', # Step size for building Lanczos matrix & CG (instanton) 

225 'qmaxmove', # Max step size (instanton) 

226 'qdt', # Timestep for quickmin minimization (instanton) 

227 'qtpz', # Temperature (instanton) 

228 'qftol', # Tolerance (instanton) 

229] 

230 

231exp_keys = [ 

232 'ediff', # stopping-criterion for electronic upd. 

233 'ediffg', # stopping-criterion for ionic upd. 

234 'symprec', # precession in symmetry routines 

235 # The next keywords pertain to the VTST add-ons from Graeme Henkelman's 

236 # group at UT Austin 

237 'fdstep', # Finite diference step for IOPT = 1 or 2 

238] 

239 

240string_keys = [ 

241 'algo', # algorithm: Normal (Davidson) | Fast | Very_Fast (RMM-DIIS) 

242 'gga', # xc-type: PW PB LM or 91 (LDA if not set) 

243 'metagga', # 

244 'prec', # Precission of calculation (Low, Normal, Accurate) 

245 'system', # name of System 

246 'precfock', # FFT grid in the HF related routines 

247 'radeq', # Which type of radial equations to use for rel. core calcs. 

248 'localized_basis', # Basis to use in CRPA 

249 'proutine', # Select profiling routine 

250] 

251 

252int_keys = [ 

253 'ialgo', # algorithm: use only 8 (CG) or 48 (RMM-DIIS) 

254 'ibrion', # ionic relaxation: 0-MD 1-quasi-New 2-CG 

255 'icharg', # charge: 0-WAVECAR 1-CHGCAR 2-atom 10-const 

256 'idipol', # monopol/dipol and quadropole corrections 

257 'images', # number of images for NEB calculation 

258 'iniwav', # initial electr wf. : 0-lowe 1-rand 

259 'isif', # calculate stress and what to relax 

260 'ismear', # part. occupancies: -5 Blochl -4-tet -1-fermi 0-gaus >0 MP 

261 'ispin', # spin-polarized calculation 

262 'istart', # startjob: 0-new 1-cont 2-samecut 

263 'isym', # symmetry: 0-nonsym 1-usesym 2-usePAWsym 

264 'iwavpr', # prediction of wf.: 0-non 1-charg 2-wave 3-comb 

265 'kpar', # k-point parallelization paramater 

266 'ldauprint', # 0-silent, 1-occ. matrix written to OUTCAR, 2-1+pot. matrix 

267 # written 

268 'ldautype', # L(S)DA+U: 1-Liechtenstein 2-Dudarev 4-Liechtenstein(LDAU) 

269 'lmaxmix', # 

270 'lorbit', # create PROOUT 

271 'maxmix', # 

272 'ngx', # FFT mesh for wavefunctions, x 

273 'ngxf', # FFT mesh for charges x 

274 'ngy', # FFT mesh for wavefunctions, y 

275 'ngyf', # FFT mesh for charges y 

276 'ngz', # FFT mesh for wavefunctions, z 

277 'ngzf', # FFT mesh for charges z 

278 'nbands', # Number of bands 

279 'nblk', # blocking for some BLAS calls (Sec. 6.5) 

280 'nbmod', # specifies mode for partial charge calculation 

281 'nelm', # nr. of electronic steps (default 60) 

282 'nelmdl', # nr. of initial electronic steps 

283 'nelmin', 

284 'nfree', # number of steps per DOF when calculting Hessian using 

285 # finite differences 

286 'nkred', # define sub grid of q-points for HF with 

287 # nkredx=nkredy=nkredz 

288 'nkredx', # define sub grid of q-points in x direction for HF 

289 'nkredy', # define sub grid of q-points in y direction for HF 

290 'nkredz', # define sub grid of q-points in z direction for HF 

291 'nomega', # number of frequency points 

292 'nomegar', # number of frequency points on real axis 

293 'npar', # parallelization over bands 

294 'nsim', # evaluate NSIM bands simultaneously if using RMM-DIIS 

295 'nsw', # number of steps for ionic upd. 

296 'nupdown', # fix spin moment to specified value 

297 'nwrite', # verbosity write-flag (how much is written) 

298 'vdwgr', # extra keyword for Andris program 

299 'vdwrn', # extra keyword for Andris program 

300 'voskown', # use Vosko, Wilk, Nusair interpolation 

301 # The next keywords pertain to the VTST add-ons from Graeme Henkelman's 

302 # group at UT Austin 

303 'ichain', # Flag for controlling which method is being used (0=NEB, 

304 # 1=DynMat, 2=Dimer, 3=Lanczos) if ichain > 3, then both 

305 # IBRION and POTIM are automatically set in the INCAR file 

306 'iopt', # Controls which optimizer to use. for iopt > 0, ibrion = 3 

307 # and potim = 0.0 

308 'snl', # Maximum dimentionality of the Lanczos matrix 

309 'lbfgsmem', # Steps saved for inverse Hessian for IOPT = 1 (LBFGS) 

310 'fnmin', # Max iter. before adjusting dt and alpha for IOPT = 7 (FIRE) 

311 'icorelevel', # core level shifts 

312 'clnt', # species index 

313 'cln', # main quantum number of excited core electron 

314 'cll', # l quantum number of excited core electron 

315 'ivdw', # Choose which dispersion correction method to use 

316 'nbandsgw', # Number of bands for GW 

317 'nbandso', # Number of occupied bands for electron-hole treatment 

318 'nbandsv', # Number of virtual bands for electron-hole treatment 

319 'ncore', # Number of cores per band, equal to number of cores divided 

320 # by npar 

321 'mdalgo', # Determines which MD method of Tomas Bucko to use 

322 'nedos', # Number of grid points in DOS 

323 'turbo', # Ewald, 0 = Normal, 1 = PME 

324 'omegapar', # Number of groups for response function calc. 

325 'taupar', # (Possibly Depricated) Number of groups in real time for response function calc. 

326 'ntaupar', # Number of groups in real time for response function calc. 

327 'antires', # How to treat antiresonant part of response function 

328 'magatom', # Index of atom at which to place magnetic field (NMR) 

329 'jatom', # Index of atom at which magnetic moment is evaluated (NMR) 

330 'ichibare', # chi_bare stencil size (NMR) 

331 'nbas', # Undocumented Bond-Boost parameter (GH patches) 

332 'rmds', # Undocumented Bond-Boost parameter (GH patches) 

333 'ilbfgsmem', # Number of histories to store for LBFGS (GH patches) 

334 'vcaimages', # Undocumented parameter (GH patches) 

335 'ntemper', # Undocumented subspace diagonalization param. (GH patches) 

336 'ncshmem', # Share memory between this many cores on each process 

337 'lmaxtau', # Undocumented MetaGGA parameter (prob. max ang.mom. for tau) 

338 'kinter', # Additional finer grid (?) 

339 'ibse', # Type of BSE calculation 

340 'nbseeig', # Number of BSE wfns to write 

341 'naturalo', # Use NATURALO (?) 

342 'nbandsexact', # Undocumented parameter 

343 'nbandsgwlow', # Number of bands for which shifts are calculated 

344 'nbandslf', # Number of bands included in local field effect calc. 

345 'omegagrid', # Undocumented parameter 

346 'telescope', # Undocumented parameter 

347 'maxmem', # Amount of memory to allocate per core in MB 

348 'nelmhf', # Number of iterations for HF part (GW) 

349 'dim', # Undocumented parameter 

350 'nkredlf', # Reduce k-points for local field effects 

351 'nkredlfx', # Reduce k-points for local field effects in X 

352 'nkredlfy', # Reduce k-points for local field effects in Y 

353 'nkredlfz', # Reduce k-points for local field effects in Z 

354 'lmaxmp2', # Undocumented parameter 

355 'switch', # Undocumented dimer parameter 

356 'findiff', # Use forward (1) or central (2) finite difference for dimer 

357 'engine', # Undocumented dimer parameter 

358 'restartcg', # Undocumented dimer parameter 

359 'thermostat', # Deprecated parameter for selecting MD method (use MDALGO) 

360 'scaling', # After how many steps velocities should be rescaled 

361 'shakemaxiter', # Maximum # of iterations in SHAKE algorithm 

362 'equi_regime', # Number of steps to equilibrate for 

363 'hills_bin', # Update metadynamics bias after this many steps 

364 'hills_maxstride', # Undocumented metadynamics parameter 

365 'dvvehistory', # Undocumented parameter 

366 'ipead', # Undocumented parameter 

367 'ngaus', # Undocumented charge fitting parameter 

368 'exxoep', # Undocumented HF parameter 

369 'fourorbit', # Undocumented HF parameter 

370 'model_gw', # Undocumented HF parameter 

371 'hflmax', # Maximum L quantum number for HF calculation 

372 'lmaxfock', # Maximum L quantum number for HF calc. (same as above) 

373 'lmaxfockae', # Undocumented HF parameter 

374 'nmaxfockae', # Undocumented HF parameter 

375 'nblock_fock', # Undocumented HF parameter 

376 'idiot', # Determines which warnings/errors to print 

377 'nrmm', # Number of RMM-DIIS iterations 

378 'mremove', # Undocumented mixing parameter 

379 'inimix', # Undocumented mixing parameter 

380 'mixpre', # Undocumented mixing parameter 

381 'nelmall', # Undocumented parameter 

382 'nblock', # How frequently to write data 

383 'kblock', # How frequently to write data 

384 'npaco', # Undocumented pair correlation function parameter 

385 'lmaxpaw', # Max L quantum number for on-site charge expansion 

386 'irestart', # Undocumented parameter 

387 'nreboot', # Undocumented parameter 

388 'nmin', # Undocumented parameter 

389 'nlspline', # Undocumented parameter 

390 'ispecial', # "Select undocumented and unsupported special features" 

391 'rcrep', # Number of steps between printing relaxed core info 

392 'rcndl', # Wait this many steps before updating core density 

393 'rcstrd', # Relax core density after this many SCF steps 

394 'vdw_idampf', # Select type of damping function for TS vdW 

395 'i_constrained_m', # Select type of magmom. constraint to use 

396 'igpar', # "G parallel" direction for Berry phase calculation 

397 'nppstr', # Number of kpts in "igpar' direction for Berry phase calc. 

398 'nbands_out', # Undocumented QP parameter 

399 'kpts_out', # Undocumented QP parameter 

400 'isp_out', # Undocumented QP parameter 

401 'nomega_out', # Undocumented QP parameter 

402 'maxiter_ft', # Max iterations for sloppy Remez algorithm 

403 'nmaxalt', # Max sample points for alternant in Remez algorithms 

404 'itmaxlsq', # Max iterations in LSQ search algorithm 

405 'ndatalsq', # Number of sample points for LSQ search algorithm 

406 'ncore_in_image1', # Undocumented parameter 

407 'kimages', # Undocumented parameter 

408 'ncores_per_band', # Undocumented parameter 

409 'maxlie', # Max iterations in CRPA diagonalization routine 

410 'ncrpalow', # Undocumented CRPA parameter 

411 'ncrpahigh', # Undocumented CRPA parameter 

412 'nwlow', # Undocumented parameter 

413 'nwhigh', # Undocumented parameter 

414 'nkopt', # Number of k-points to include in Optics calculation 

415 'nkoffopt', # K-point "counter offset" for Optics 

416 'nbvalopt', # Number of valence bands to write in OPTICS file 

417 'nbconopt', # Number of conduction bands to write in OPTICS file 

418 'ch_nedos', # Number dielectric function calculation grid points for XAS 

419 'plevel', # No timings for routines with "level" higher than this 

420 'qnl', # Lanczos matrix size (instanton) 

421] 

422 

423bool_keys = [ 

424 'addgrid', # finer grid for augmentation charge density 

425 'kgamma', # The generated kpoint grid (from KSPACING) is either 

426 # centred at the $\Gamma$ 

427 # point (e.g. includes the $\Gamma$ point) 

428 # (KGAMMA=.TRUE.) 

429 'laechg', # write AECCAR0/AECCAR1/AECCAR2 

430 'lasph', # non-spherical contributions to XC energy (and pot for 

431 # VASP.5.X) 

432 'lasync', # overlap communcation with calculations 

433 'lcharg', # 

434 'lcorr', # Harris-correction to forces 

435 'ldau', # L(S)DA+U 

436 'ldiag', # algorithm: perform sub space rotation 

437 'ldipol', # potential correction mode 

438 'lelf', # create ELFCAR 

439 'lepsilon', # enables to calculate and to print the BEC tensors 

440 'lhfcalc', # switch to turn on Hartree Fock calculations 

441 'loptics', # calculate the frequency dependent dielectric matrix 

442 'lpard', # evaluate partial (band and/or k-point) decomposed charge 

443 # density 

444 'lplane', # parallelisation over the FFT grid 

445 'lscalapack', # switch off scaLAPACK 

446 'lscalu', # switch of LU decomposition 

447 'lsepb', # write out partial charge of each band separately? 

448 'lsepk', # write out partial charge of each k-point separately? 

449 'lthomas', # 

450 'luse_vdw', # Invoke vdW-DF implementation by Klimes et. al 

451 'lvdw', # Invoke DFT-D2 method of Grimme 

452 'lvhar', # write Hartree potential to LOCPOT (vasp 5.x) 

453 'lvtot', # create WAVECAR/CHGCAR/LOCPOT 

454 'lwave', # 

455 # The next keywords pertain to the VTST add-ons from Graeme Henkelman's 

456 # group at UT Austin 

457 'lclimb', # Turn on CI-NEB 

458 'ltangentold', # Old central difference tangent 

459 'ldneb', # Turn on modified double nudging 

460 'lnebcell', # Turn on SS-NEB 

461 'lglobal', # Optmize NEB globally for LBFGS (IOPT = 1) 

462 'llineopt', # Use force based line minimizer for translation (IOPT = 1) 

463 'lbeefens', # Switch on print of BEE energy contributions in OUTCAR 

464 'lbeefbas', # Switch off print of all BEEs in OUTCAR 

465 'lcalcpol', # macroscopic polarization (vasp5.2). 'lcalceps' 

466 'lcalceps', # Macroscopic dielectric properties and Born effective charge 

467 # tensors (vasp 5.2) 

468 'lvdw', # Turns on dispersion correction 

469 'lvdw_ewald', # Turns on Ewald summation for Grimme's DFT-D2 and 

470 # Tkatchenko and Scheffler's DFT-TS dispersion correction 

471 'lspectral', # Use the spectral method to calculate independent particle 

472 # polarizability 

473 'lrpa', # Include local field effects on the Hartree level only 

474 'lwannier90', # Switches on the interface between VASP and WANNIER90 

475 'lsorbit', # Enable spin-orbit coupling 

476 'lsol', # turn on solvation for Vaspsol 

477 'lautoscale', # automatically calculate inverse curvature for VTST LBFGS 

478 'interactive', # Enables interactive calculation for VaspInteractive 

479 'lauger', # Perform Auger calculation (Auger) 

480 'lauger_eeh', # Calculate EEH processes (Auger) 

481 'lauger_ehh', # Calculate EHH processes (Auger) 

482 'lauger_collect', # Collect wfns before looping over k-points (Auger) 

483 'lauger_dhdk', # Auto-determine E. window width from E. derivs. (Auger) 

484 'lauger_jit', # Distribute wavefunctions for k1-k4 (Auger) 

485 'orbitalmag', # Enable orbital magnetization (NMR) 

486 'lchimag', # Use linear response for shielding tensor (NMR) 

487 'lwrtcur', # Write response of current to mag. field to file (NMR) 

488 'lnmr_sym_red', # Reduce symmetry for finite difference (NMR) 

489 'lzora', # Use ZORA approximation in linear-response NMR (NMR) 

490 'lbone', # Use B-component in AE one-center terms for LR NMR (NMR) 

491 'lmagbloch', # Use Bloch summations to obtain orbital magnetization (NMR) 

492 'lgauge', # Use gauge transformation for zero moment terms (NMR) 

493 'lbfconst', # Use constant B-field with sawtooth vector potential (NMR) 

494 'nucind', # Use nuclear independent calculation (NMR) 

495 'lnicsall', # Use all grid points for 'nucind' calculation (NMR) 

496 'llraug', # Use two-center corrections for induced B-field (NMR) 

497 'lbbm', # Undocumented Bond-Boost parameter (GH patches) 

498 'lnoncollinear', # Do non-collinear spin polarized calculation 

499 'bfgsdfp', # Undocumented BFGS parameter (GH patches) 

500 'linemin', # Use line minimization (GH patches) 

501 'ldneborg', # Undocumented NEB parameter (GH patches) 

502 'dseed', # Undocumented dimer parameter (GH patches) 

503 'linteract', # Undocumented parameter (GH patches) 

504 'lmpmd', # Undocumented parameter (GH patches) 

505 'ltwodim', # Makes stress tensor two-dimensional (GH patches) 

506 'fmagflag', # Use force magnitude as convergence criterion (GH patches) 

507 'ltemper', # Use subspace diagonalization (?) (GH patches) 

508 'qmflag', # Undocumented FIRE parameter (GH patches) 

509 'lmixtau', # Undocumented MetaGGA parameter 

510 'ljdftx', # Undocumented VASPsol parameter (VASPsol) 

511 'lrhob', # Write the bound charge density (VASPsol) 

512 'lrhoion', # Write the ionic charge density (VASPsol) 

513 'lnabla', # Undocumented parameter 

514 'linterfast', # Interpolate in K using linear response routines 

515 'lvel', # Undocumented parameter 

516 'lrpaforce', # Calculate RPA forces 

517 'lhartree', # Use IP approx. in BSE (testing only) 

518 'ladder', # Use ladder diagrams 

519 'lfxc', # Use approximate ladder diagrams 

520 'lrsrpa', # Undocumented parameter 

521 'lsingles', # Calculate HF singles 

522 'lfermigw', # Iterate Fermi level 

523 'ltcte', # Undocumented parameter 

524 'ltete', # Undocumented parameter 

525 'ltriplet', # Undocumented parameter 

526 'lfxceps', # Undocumented parameter 

527 'lfxheg', # Undocumented parameter 

528 'l2order', # Undocumented parameter 

529 'lmp2lt', # Undocumented parameter 

530 'lgwlf', # Undocumented parameter 

531 'lusew', # Undocumented parameter 

532 'selfenergy', # Undocumented parameter 

533 'oddonlygw', # Avoid gamma point in response function calc. 

534 'evenonlygw', # Avoid even points in response function calc. 

535 'lspectralgw', # More accurate self-energy calculation 

536 'ch_lspec', # Calculate matrix elements btw. core and conduction states 

537 'fletcher_reeves', # Undocumented dimer parameter 

538 'lidm_selective', # Undocumented dimer parameter 

539 'lblueout', # Write output of blue-moon algorithm 

540 'hills_variable_w', # Enable variable-width metadynamics bias 

541 'dvvminus', # Undocumented parameter 

542 'lpead', # Calculate cell-periodic orbital derivs. using finite diff. 

543 'skip_edotp', # Skip updating elec. polarization during scf 

544 'skip_scf', # Skip calculation w/ local field effects 

545 'lchgfit', # Turn on charge fitting 

546 'lgausrc', # Undocumented charge fitting parameter 

547 'lstockholder', # Enable ISA charge fitting (?) 

548 'lsymgrad', # Restore symmetry of gradient (HF) 

549 'lhfone', # Calculate one-center terms (HF) 

550 'lrscor', # Include long-range correlation (HF) 

551 'lrhfcalc', # Include long-range HF (HF) 

552 'lmodelhf', # Model HF calculation (HF) 

553 'shiftred', # Undocumented HF parameter 

554 'hfkident', # Undocumented HF parameter 

555 'oddonly', # Undocumented HF parameter 

556 'evenonly', # Undocumented HF parameter 

557 'lfockaedft', # Undocumented HF parameter 

558 'lsubsrot', # Enable subspace rotation diagonalization 

559 'mixfirst', # Mix before diagonalization 

560 'lvcader', # Calculate derivs. w.r.t. VCA parameters 

561 'lcompat', # Enable "full compatibility" 

562 'lmusic', # "Joke" parameter 

563 'ldownsample', # Downsample WAVECAR to fewer k-points 

564 'lscaaware', # Disable ScaLAPACK for some things but not all 

565 'lorbitalreal', # Undocumented parameter 

566 'lmetagga', # Undocumented parameter 

567 'lspiral', # Undocumented parameter 

568 'lzeroz', # Undocumented parameter 

569 'lmono', # Enable "monopole" corrections 

570 'lrelcore', # Perform relaxed core calculation 

571 'lmimicfc', # Mimic frozen-core calcs. for relaxed core calcs. 

572 'lmatchrw', # Match PS partial waves at RWIGS? (otherwise PAW cutoff) 

573 'ladaptelin', # Linearize core state energies to avoid divergences 

574 'lonlysemicore', # Only linearize semi-core state energies 

575 'gga_compat', # Enable backwards-compatible symmetrization of GGA derivs. 

576 'lrelvol', # Undocumented classical vdW parameter 

577 'lj_only', # Undocumented classical vdW parameter 

578 'lvdwscs', # Include self-consistent screening in TS vdW correction 

579 'lcfdm', # Use coupled fluctuating dipoles model for TS vdW 

580 'lvdw_sametype', # Include interactions between atoms of the same type 

581 'lrescaler0', # Rescale damping parameters in SCS vdW correction 

582 'lscsgrad', # Calculate gradients for TS+SCS vdW correction energies 

583 'lvdwexpansion', # Write 2-6 body contribs. to MBD vdW correction energy 

584 'lvdw_relvolone', # Undocumented classical vdW parameter 

585 'lberry', # Enable Berry-phase calculation 

586 'lpade_fit', # Undocumented QP parameter 

587 'lkproj', # Enable projection onto k-points 

588 'l_wr_moments', # Undocumented parameter 

589 'l_wr_density', # Undocumented parameter 

590 'lkotani', # Undocumented parameter 

591 'ldyson', # Undocumented parameter 

592 'laddherm', # Undocumented parameter 

593 'lcrpaplot', # Plot bands used in CRPA response func. calc. 

594 'lplotdis', # Plot disentangled bands in CRPA response func. calc. 

595 'ldisentangle', # Disentangle bands in CRPA 

596 'lweighted', # "Weighted" CRPA approach 

597 'luseorth_lcaos', # Use orthogonalized LCAOs in CRPA 

598 'lfrpa', # Use full RPA in CRPA 

599 'lregularize', # Regularize projectors in CRPA 

600 'ldrude', # Include Drude term in CRPA 

601 'ldmatrix', # Undocumented parameter 

602 'lefg', # Calculate electric field gradient at atomic nuclei 

603 'lhyperfine', # Enable Hyperfine calculation 

604 'lwannier', # Enable Wannier interface 

605 'localize', # Undocumented Wannier parameter 

606 'lintpol_wpot', # Interpolate WPOT for Wannier 

607 'lintpol_orb', # Interpolate orbitals for Wannier 

608 'lintpol_kpath', # Interpolate bandstructure on given kpath for Wannier 

609 'lintpol_kpath_orb', # Interpolate orbitals on given kpath for Wannier 

610 'lread_eigenvalues', # Use Eigenvalues from EIGENVALUES.INT file 

611 'lintpol_velocity', # Interpolate electron velocity for Wannier 

612 'lintpol_conductivity', # Interpolate conductivity for Wannier 

613 'lwannierinterpol', # Undocumented Wannier parameter 

614 'wanproj', # Undocumented Wannier parameter 

615 'lorbmom', # Undocumented LDA+U parameter 

616 'lwannier90_run', # Undocumented WANNIER90 parameter 

617 'lwrite_wanproj', # Write UWAN files for WANNIER90 

618 'lwrite_unk', # Write UNK files for WANNIER90 

619 'lwrite_mmn_amn', # Write MMN and AMN files for WANNIER90 

620 'lread_amn', # Read AMN files instead of recomputing (WANNIER90) 

621 'lrhfatm', # Undocumented HF parameter 

622 'lvpot', # Calculate unscreened potential 

623 'lwpot', # Calculate screened potential 

624 'lwswq', # Undocumented parameter 

625 'pflat', # Only print "flat" timings to OUTCAR 

626 'qifcg', # Use CG instead of quickmin (instanton) 

627 'qdo_ins', # Find instanton 

628 'qdo_pre', # Calculate prefactor (instanton) 

629 # The next keyword pertains to the periodic NBO code of JR Schmidt's group 

630 # at UW-Madison (https://github.com/jrschmidt2/periodic-NBO) 

631 'lnbo', # Enable NBO analysis 

632] 

633 

634list_int_keys = [ 

635 'iband', # bands to calculate partial charge for 

636 'kpuse', # k-point to calculate partial charge for 

637 'ldaul', # DFT+U parameters, overruled by dict key 'ldau_luj' 

638 'random_seed', # List of ints used to seed RNG for advanced MD routines 

639 # (Bucko) 

640 'auger_bmin_eeh', # 4 ints | Various undocumented parameters for Auger 

641 'auger_bmax_eeh', # 4 ints | calculations 

642 'auger_bmin_ehh', # 4 ints | 

643 'auger_bmax_ehh', # 4 ints | 

644 'balist', # nbas ints | Undocumented Bond-Boost parameter (GH patches) 

645 'kpoint_bse', # 4 ints | Undocumented parameter 

646 'nsubsys', # <=3 ints | Last atom # for each of up to 3 thermostats 

647 'vdw_refstate', # ntyp ints | Undocumented classical vdW parameter 

648 'vdw_mbd_size', # 3 ints | Supercell size for TS MBD vdW correction 

649 'nbands_index', # nbands_out ints | Undocumented QP parameter 

650 'kpts_index', # kpts_out ints | Undocumented QP parameter 

651 'isp_index', # isp_out ints | Undocumented QP parameter 

652 'nomega_index', # nomega_out ints | Undocumented QP parameter 

653 'ntarget_states', # nbands ints | Undocumented CRPA parameter 

654 'wanproj_i', # nions ints | Undocumented Wannier parameter 

655 'wanproj_l', # ? ints | Undocumented Wannier parameter 

656] 

657 

658list_bool_keys = [ 

659 'lattice_constraints', # 3 bools | Undocumented advanced MD parameter 

660 'lrctype', # ntyp bools | Enable relaxed-core calc. for these atoms 

661 'lvdw_onecell', # 3 bools | Enable periodicity in A, B, C vector for vdW 

662] 

663 

664list_float_keys = [ 

665 'dipol', # center of cell for dipol 

666 'eint', # energy range to calculate partial charge for 

667 'ferwe', # Fixed band occupation (spin-paired) 

668 'ferdo', # Fixed band occupation (spin-plarized) 

669 'magmom', # initial magnetic moments 

670 'ropt', # number of grid points for non-local proj in real space 

671 'rwigs', # Wigner-Seitz radii 

672 'ldauu', # ldau parameters, has potential to redundant w.r.t. dict 

673 'ldauj', # key 'ldau_luj', but 'ldau_luj' can't be read direct from 

674 # the INCAR (since it needs to know information about atomic 

675 # species. In case of conflict 'ldau_luj' gets written out 

676 # when a calculation is set up 

677 'vdw_c6', # List of floats of C6 parameters (J nm^6 mol^-1) for each 

678 # species (DFT-D2 and DFT-TS) 

679 'vdw_c6au', # List of floats of C6 parameters (a.u.) for each species 

680 # (DFT-TS) 

681 'vdw_r0', # List of floats of R0 parameters (angstroms) for each 

682 # species (DFT-D2 and DFT-TS) 

683 'vdw_r0au', # List of floats of R0 parameters (a.u.) for each species 

684 # (DFT-TS) 

685 'vdw_alpha', # List of floats of free-atomic polarizabilities for each 

686 # species (DFT-TS) 

687 'langevin_gamma', # List of floats for langevin friction coefficients 

688 'auger_emin_eeh', # 4 floats | Various undocumented parameters for Auger 

689 'auger_emax_eeh', # 4 floats | calculations 

690 'auger_emin_ehh', # 4 floats | 

691 'auger_emax_ehh', # 4 floats | 

692 'avecconst', # 3 floats | magnitude of magnetic moment (NMR) 

693 'magdipol', # 3 floats | magnitude of magnetic dipole (NMR) 

694 'bconst', # 3 floats | magnitude of constant magnetic field (NMR) 

695 'magpos', # 3 floats | position for magnetic moment w/ 'nucind' (NMR) 

696 'bext', # 3 floats | Undocumented (probably external magnetic field) 

697 'core_c', # ntyp floats | pseudo-core charge magnitude (VASPsol) 

698 'sigma_rc_k', # ntyp floats | width of pseudo-core gaussians (VASPsol) 

699 'darwinr', # ntypd (?) floats | Undocumented parameter 

700 'darwinv', # ntypd (?) floats | Undocumented parameter 

701 'dummy_k', # ? floats | Force const. connecting dummy atoms to sys. 

702 'dummy_r0', # ? floats | Minimum dist., ang., etc. for dummy atom DOFs 

703 'dummy_positions', # 3 floats | Position of dummy atom(s?) 

704 'psubsys', # <=3 floats | Coll. prob. for each of up to 3 thermostats 

705 'tsubsys', # <=3 floats | Temp. for each of up to 3 thermostats 

706 'increm', # ? floats | Undocumented advanced MD parameter 

707 'value_min', # ? floats | Undocumented advanced MD parameter 

708 'value_max', # ? floats | Undocumented advanced MD parameter 

709 'hills_position', # ? floats | Dummy particle(s) pos. for metadynamics 

710 'hills_velocity', # ? floats | Dummy particle(s) vel. for metadynamics 

711 'spring_k', # ? floats | Spring constant for harmonic constraints 

712 'spring_r0', # ? floats | Spring minima for harmonic constraints 

713 'spring_v0', # ? floats | Initial velocity of harmonic constraints 

714 'hills_wall_lower', # ? floats | Undocumented metadynamics parameter 

715 'hills_wall_upper', # ? floats | Undocumented metadynamics parameter 

716 'efield_pead', # 3 floats | homogeneous electric field for PEAD calc. 

717 'zct', # ? floats | Undocumented charge fitting parameter 

718 'rgaus', # ? floats | Undocumented charge fitting parameter 

719 'hfalpha', # 10 floats | Undocumented HF parameter 

720 'mcalpha', # 10 floats | Undocumented HF parameter 

721 'saxis', # 3 floats | Coordinate for collinear spin calculations 

722 'vca', # ? floats | Atom weight for VCA calculations 

723 'stm', # 7 floats | "range for STM data" 

724 'qspiral', # 3 floats | Undocumented parameter 

725 'external_stress', # 6 floats | Target stress (adds w/ external_pressure) 

726 'm_constr', # 3*nions floats | Local magmom assigned to each spin DOF 

727 'quad_efg', # ntyp floats | Nuclear quadrupole moments 

728 'ngyromag', # ntyp floats | Nuclear gyromagnetic ratios 

729 'rcrhocut', # ntyp floats | Core density cutoff rad. for HF relcore calc 

730 'ofield_k', # 3 floats | Undocumented parameter 

731 'paripot', # ? floats | Undocumented parameter 

732 'smearings', # ? floats | ismear,sigma smearing params to loop over 

733 'wanproj_e', # 2 floats | Undocumented Wannier parameter 

734] 

735 

736special_keys = [ 

737 'lreal', # non-local projectors in real space 

738] 

739 

740dict_keys = [ 

741 'ldau_luj', # dictionary with L(S)DA+U parameters, e.g. {'Fe':{'L':2, 

742 # 'U':4.0, 'J':0.9}, ...} 

743] 

744 

745keys: List[str] = [ 

746 # 'NBLOCK' and KBLOCK inner block; outer block 

747 # 'NPACO' and APACO distance and nr. of slots for P.C. 

748 # 'WEIMIN, EBREAK, DEPER special control tags 

749] 

750 

751 

752class GenerateVaspInput: 

753 # Parameters corresponding to 'xc' settings. This may be modified 

754 # by the user in-between loading calculators.vasp submodule and 

755 # instantiating the calculator object with calculators.vasp.Vasp() 

756 xc_defaults = { 

757 'lda': { 

758 'pp': 'LDA' 

759 }, 

760 # GGAs 

761 'pw91': { 

762 'pp': 'PW91', 

763 'gga': '91' 

764 }, 

765 'pbe': { 

766 'pp': 'PBE', 

767 'gga': 'PE' 

768 }, 

769 'pbesol': { 

770 'gga': 'PS' 

771 }, 

772 'revpbe': { 

773 'gga': 'RE' 

774 }, 

775 'rpbe': { 

776 'gga': 'RP' 

777 }, 

778 'am05': { 

779 'gga': 'AM' 

780 }, 

781 # Meta-GGAs 

782 'tpss': { 

783 'metagga': 'TPSS' 

784 }, 

785 'revtpss': { 

786 'metagga': 'RTPSS' 

787 }, 

788 'm06l': { 

789 'metagga': 'M06L' 

790 }, 

791 'ms0': { 

792 'metagga': 'MS0' 

793 }, 

794 'ms1': { 

795 'metagga': 'MS1' 

796 }, 

797 'ms2': { 

798 'metagga': 'MS2' 

799 }, 

800 'scan': { 

801 'metagga': 'SCAN' 

802 }, 

803 'scan-rvv10': { 

804 'metagga': 'SCAN', 

805 'luse_vdw': True, 

806 'bparam': 15.7 

807 }, 

808 'mbj': { 

809 # Modified Becke-Johnson 

810 'metagga': 'MBJ', 

811 }, 

812 'tb09': { 

813 # Alias for MBJ 

814 'metagga': 'MBJ', 

815 }, 

816 # vdW-DFs 

817 'vdw-df': { 

818 'gga': 'RE', 

819 'luse_vdw': True, 

820 'aggac': 0. 

821 }, 

822 'vdw-df-cx': { 

823 'gga': 'CX', 

824 'luse_vdw': True, 

825 'aggac': 0. 

826 }, 

827 'vdw-df-cx0p': { 

828 'gga': 'CX', 

829 'luse_vdw': True, 

830 'aggac': 0., 

831 'lhfcalc': True, 

832 'aexx': 0.2, 

833 'aggax': 0.8 

834 }, 

835 'optpbe-vdw': { 

836 'gga': 'OR', 

837 'luse_vdw': True, 

838 'aggac': 0.0 

839 }, 

840 'optb88-vdw': { 

841 'gga': 'BO', 

842 'luse_vdw': True, 

843 'aggac': 0.0, 

844 'param1': 1.1 / 6.0, 

845 'param2': 0.22 

846 }, 

847 'optb86b-vdw': { 

848 'gga': 'MK', 

849 'luse_vdw': True, 

850 'aggac': 0.0, 

851 'param1': 0.1234, 

852 'param2': 1.0 

853 }, 

854 'vdw-df2': { 

855 'gga': 'ML', 

856 'luse_vdw': True, 

857 'aggac': 0.0, 

858 'zab_vdw': -1.8867 

859 }, 

860 'rev-vdw-df2': { 

861 'gga': 'MK', 

862 'luse_vdw': True, 

863 'param1': 0.1234, 

864 'param2': 0.711357, 

865 'zab_vdw': -1.8867, 

866 'aggac': 0.0 

867 }, 

868 'beef-vdw': { 

869 'gga': 'BF', 

870 'luse_vdw': True, 

871 'zab_vdw': -1.8867 

872 }, 

873 # Hartree-Fock and hybrids 

874 'hf': { 

875 'lhfcalc': True, 

876 'aexx': 1.0, 

877 'aldac': 0.0, 

878 'aggac': 0.0 

879 }, 

880 'b3lyp': { 

881 'gga': 'B3', 

882 'lhfcalc': True, 

883 'aexx': 0.2, 

884 'aggax': 0.72, 

885 'aggac': 0.81, 

886 'aldac': 0.19 

887 }, 

888 'pbe0': { 

889 'gga': 'PE', 

890 'lhfcalc': True 

891 }, 

892 'hse03': { 

893 'gga': 'PE', 

894 'lhfcalc': True, 

895 'hfscreen': 0.3 

896 }, 

897 'hse06': { 

898 'gga': 'PE', 

899 'lhfcalc': True, 

900 'hfscreen': 0.2 

901 }, 

902 'hsesol': { 

903 'gga': 'PS', 

904 'lhfcalc': True, 

905 'hfscreen': 0.2 

906 }, 

907 # MN-VFM functionals 

908 'sogga': { 

909 'gga': 'SA' 

910 }, 

911 'sogga11': { 

912 'gga': 'S1' 

913 }, 

914 'sogga11-x': { 

915 'gga': 'SX', 

916 'lhfcalc': True, 

917 'aexx': 0.401 

918 }, 

919 'n12': { 

920 'gga': 'N2' 

921 }, 

922 'n12-sx': { 

923 'gga': 'NX', 

924 'lhfcalc': True, 

925 'lhfscreen': 0.2 

926 }, 

927 'mn12l': { 

928 'metagga': 'MN12L' 

929 }, 

930 'gam': { 

931 'gga': 'GA' 

932 }, 

933 'mn15l': { 

934 'metagga': 'MN15L' 

935 }, 

936 'hle17': { 

937 'metagga': 'HLE17' 

938 }, 

939 'revm06l': { 

940 'metagga': 'revM06L' 

941 }, 

942 'm06sx': { 

943 'metagga': 'M06SX', 

944 'lhfcalc': True, 

945 'hfscreen': 0.189, 

946 'aexx': 0.335 

947 } 

948 } 

949 

950 # environment variable for PP paths 

951 VASP_PP_PATH = 'VASP_PP_PATH' 

952 

953 def __init__(self, restart=None): 

954 self.float_params = {} 

955 self.exp_params = {} 

956 self.string_params = {} 

957 self.int_params = {} 

958 self.bool_params = {} 

959 self.list_bool_params = {} 

960 self.list_int_params = {} 

961 self.list_float_params = {} 

962 self.special_params = {} 

963 self.dict_params = {} 

964 for key in float_keys: 

965 self.float_params[key] = None 

966 for key in exp_keys: 

967 self.exp_params[key] = None 

968 for key in string_keys: 

969 self.string_params[key] = None 

970 for key in int_keys: 

971 self.int_params[key] = None 

972 for key in bool_keys: 

973 self.bool_params[key] = None 

974 for key in list_bool_keys: 

975 self.list_bool_params[key] = None 

976 for key in list_int_keys: 

977 self.list_int_params[key] = None 

978 for key in list_float_keys: 

979 self.list_float_params[key] = None 

980 for key in special_keys: 

981 self.special_params[key] = None 

982 for key in dict_keys: 

983 self.dict_params[key] = None 

984 

985 # Initialize internal dictionary of input parameters which are 

986 # not regular VASP keys 

987 self.input_params = { 

988 'xc': None, # Exchange-correlation recipe (e.g. 'B3LYP') 

989 'pp': None, # Pseudopotential file (e.g. 'PW91') 

990 'setups': None, # Special setups (e.g pv, sv, ...) 

991 'txt': '-', # Where to send information 

992 'kpts': (1, 1, 1), # k-points 

993 # Option to use gamma-sampling instead of Monkhorst-Pack: 

994 'gamma': False, 

995 # number of points between points in band structures: 

996 'kpts_nintersections': None, 

997 # Option to write explicit k-points in units 

998 # of reciprocal lattice vectors: 

999 'reciprocal': False, 

1000 # Switch to disable writing constraints to POSCAR 

1001 'ignore_constraints': False, 

1002 # Net charge for the whole system; determines nelect if not 0 

1003 'charge': None, 

1004 # Deprecated older parameter which works just like "charge" but 

1005 # with the sign flipped 

1006 'net_charge': None, 

1007 # Custom key-value pairs, written to INCAR with *no* type checking 

1008 'custom': {}, 

1009 } 

1010 

1011 def set_xc_params(self, xc): 

1012 """Set parameters corresponding to XC functional""" 

1013 xc = xc.lower() 

1014 if xc is None: 

1015 pass 

1016 elif xc not in self.xc_defaults: 

1017 xc_allowed = ', '.join(self.xc_defaults.keys()) 

1018 raise ValueError('{0} is not supported for xc! Supported xc values' 

1019 'are: {1}'.format(xc, xc_allowed)) 

1020 else: 

1021 # XC defaults to PBE pseudopotentials 

1022 if 'pp' not in self.xc_defaults[xc]: 

1023 self.set(pp='PBE') 

1024 self.set(**self.xc_defaults[xc]) 

1025 

1026 def set(self, **kwargs): 

1027 

1028 if (('ldauu' in kwargs) and ('ldaul' in kwargs) and ('ldauj' in kwargs) 

1029 and ('ldau_luj' in kwargs)): 

1030 raise NotImplementedError( 

1031 'You can either specify ldaul, ldauu, and ldauj OR ' 

1032 'ldau_luj. ldau_luj is not a VASP keyword. It is a ' 

1033 'dictionary that specifies L, U and J for each ' 

1034 'chemical species in the atoms object. ' 

1035 'For example for a water molecule:' 

1036 '''ldau_luj={'H':{'L':2, 'U':4.0, 'J':0.9}, 

1037 'O':{'L':2, 'U':4.0, 'J':0.9}}''') 

1038 

1039 if 'xc' in kwargs: 

1040 self.set_xc_params(kwargs['xc']) 

1041 for key in kwargs: 

1042 if key in self.float_params: 

1043 self.float_params[key] = kwargs[key] 

1044 elif key in self.exp_params: 

1045 self.exp_params[key] = kwargs[key] 

1046 elif key in self.string_params: 

1047 self.string_params[key] = kwargs[key] 

1048 elif key in self.int_params: 

1049 self.int_params[key] = kwargs[key] 

1050 elif key in self.bool_params: 

1051 self.bool_params[key] = kwargs[key] 

1052 elif key in self.list_bool_params: 

1053 self.list_bool_params[key] = kwargs[key] 

1054 elif key in self.list_int_params: 

1055 self.list_int_params[key] = kwargs[key] 

1056 elif key in self.list_float_params: 

1057 self.list_float_params[key] = kwargs[key] 

1058 elif key in self.special_params: 

1059 self.special_params[key] = kwargs[key] 

1060 elif key in self.dict_params: 

1061 self.dict_params[key] = kwargs[key] 

1062 elif key in self.input_params: 

1063 self.input_params[key] = kwargs[key] 

1064 else: 

1065 raise TypeError('Parameter not defined: ' + key) 

1066 

1067 def check_xc(self): 

1068 """Make sure the calculator has functional & pseudopotentials set up 

1069 

1070 If no XC combination, GGA functional or POTCAR type is specified, 

1071 default to PW91. Otherwise, try to guess the desired pseudopotentials. 

1072 """ 

1073 

1074 p = self.input_params 

1075 

1076 # There is no way to correctly guess the desired 

1077 # set of pseudopotentials without 'pp' being set. 

1078 # Usually, 'pp' will be set by 'xc'. 

1079 if 'pp' not in p or p['pp'] is None: 

1080 if self.string_params['gga'] is None: 

1081 p.update({'pp': 'lda'}) 

1082 elif self.string_params['gga'] == '91': 

1083 p.update({'pp': 'pw91'}) 

1084 elif self.string_params['gga'] == 'PE': 

1085 p.update({'pp': 'pbe'}) 

1086 else: 

1087 raise NotImplementedError( 

1088 "Unable to guess the desired set of pseudopotential" 

1089 "(POTCAR) files. Please do one of the following: \n" 

1090 "1. Use the 'xc' parameter to define your XC functional." 

1091 "These 'recipes' determine the pseudopotential file as " 

1092 "well as setting the INCAR parameters.\n" 

1093 "2. Use the 'gga' settings None (default), 'PE' or '91'; " 

1094 "these correspond to LDA, PBE and PW91 respectively.\n" 

1095 "3. Set the POTCAR explicitly with the 'pp' flag. The " 

1096 "value should be the name of a folder on the VASP_PP_PATH" 

1097 ", and the aliases 'LDA', 'PBE' and 'PW91' are also" 

1098 "accepted.\n") 

1099 

1100 if (p['xc'] is not None and p['xc'].lower() == 'lda' 

1101 and p['pp'].lower() != 'lda'): 

1102 warnings.warn("XC is set to LDA, but PP is set to " 

1103 "{0}. \nThis calculation is using the {0} " 

1104 "POTCAR set. \n Please check that this is " 

1105 "really what you intended!" 

1106 "\n".format(p['pp'].upper())) 

1107 

1108 def _make_sort( 

1109 self, atoms: ase.Atoms, special_setups: Sequence[int] = () 

1110 ) -> Tuple[List[int], List[int]]: 

1111 symbols, _ = count_symbols(atoms, exclude=special_setups) 

1112 

1113 # Create sorting list 

1114 srt = [] # type: List[int] 

1115 srt.extend(special_setups) 

1116 

1117 for symbol in symbols: 

1118 for m, atom in enumerate(atoms): 

1119 if m in special_setups: 

1120 continue 

1121 if atom.symbol == symbol: 

1122 srt.append(m) 

1123 # Create the resorting list 

1124 resrt = list(range(len(srt))) 

1125 for n in range(len(resrt)): 

1126 resrt[srt[n]] = n 

1127 return srt, resrt 

1128 

1129 def _build_pp_list(self, 

1130 atoms, 

1131 setups=None, 

1132 special_setups: Sequence[int] = ()): 

1133 """Build the pseudopotential lists""" 

1134 

1135 p = self.input_params 

1136 

1137 if setups is None: 

1138 setups, special_setups = self._get_setups() 

1139 

1140 symbols, _ = count_symbols(atoms, exclude=special_setups) 

1141 

1142 # Potpaw folders may be identified by an alias or full name 

1143 for pp_alias, pp_folder in (('lda', 'potpaw'), ('pw91', 'potpaw_GGA'), 

1144 ('pbe', 'potpaw_PBE')): 

1145 if p['pp'].lower() == pp_alias: 

1146 break 

1147 else: 

1148 pp_folder = p['pp'] 

1149 

1150 if self.VASP_PP_PATH in os.environ: 

1151 pppaths = os.environ[self.VASP_PP_PATH].split(':') 

1152 else: 

1153 pppaths = [] 

1154 ppp_list = [] 

1155 # Setting the pseudopotentials, first special setups and 

1156 # then according to symbols 

1157 for m in special_setups: 

1158 if m in setups: 

1159 special_setup_index = m 

1160 elif str(m) in setups: 

1161 special_setup_index = str(m) # type: ignore 

1162 else: 

1163 raise Exception("Having trouble with special setup index {0}." 

1164 " Please use an int.".format(m)) 

1165 potcar = join(pp_folder, setups[special_setup_index], 'POTCAR') 

1166 for path in pppaths: 

1167 filename = join(path, potcar) 

1168 

1169 if isfile(filename) or islink(filename): 

1170 ppp_list.append(filename) 

1171 break 

1172 elif isfile(filename + '.Z') or islink(filename + '.Z'): 

1173 ppp_list.append(filename + '.Z') 

1174 break 

1175 else: 

1176 symbol = atoms.symbols[m] 

1177 msg = """Looking for {}. 

1178 No pseudopotential for symbol{} with setup {} """.format( 

1179 potcar, symbol, setups[special_setup_index]) 

1180 raise RuntimeError(msg) 

1181 

1182 for symbol in symbols: 

1183 try: 

1184 potcar = join(pp_folder, symbol + setups[symbol], 'POTCAR') 

1185 except (TypeError, KeyError): 

1186 potcar = join(pp_folder, symbol, 'POTCAR') 

1187 for path in pppaths: 

1188 filename = join(path, potcar) 

1189 

1190 if isfile(filename) or islink(filename): 

1191 ppp_list.append(filename) 

1192 break 

1193 elif isfile(filename + '.Z') or islink(filename + '.Z'): 

1194 ppp_list.append(filename + '.Z') 

1195 break 

1196 else: 

1197 msg = ("""Looking for PP for {} 

1198 The pseudopotentials are expected to be in: 

1199 LDA: $VASP_PP_PATH/potpaw/ 

1200 PBE: $VASP_PP_PATH/potpaw_PBE/ 

1201 PW91: $VASP_PP_PATH/potpaw_GGA/ 

1202  

1203 No pseudopotential for {}!""".format(potcar, symbol)) 

1204 raise RuntimeError(msg) 

1205 return ppp_list 

1206 

1207 def _get_setups(self): 

1208 p = self.input_params 

1209 

1210 special_setups = [] 

1211 

1212 # Default setup lists are available: 'minimal', 'recommended' and 'GW' 

1213 # These may be provided as a string e.g.:: 

1214 # 

1215 # calc = Vasp(setups='recommended') 

1216 # 

1217 # or in a dict with other specifications e.g.:: 

1218 # 

1219 # calc = Vasp(setups={'base': 'minimal', 'Ca': '_sv', 2: 'O_s'}) 

1220 # 

1221 # Where other keys are either atom identities or indices, and the 

1222 # corresponding values are suffixes or the full name of the setup 

1223 # folder, respectively. 

1224 

1225 # Avoid mutating the module dictionary, so we use a copy instead 

1226 # Note, it is a nested dict, so a regular copy is not enough 

1227 setups_defaults = get_default_setups() 

1228 

1229 # Default to minimal basis 

1230 if p['setups'] is None: 

1231 p['setups'] = {'base': 'minimal'} 

1232 

1233 # String shortcuts are initialised to dict form 

1234 elif isinstance(p['setups'], str): 

1235 if p['setups'].lower() in setups_defaults.keys(): 

1236 p['setups'] = {'base': p['setups']} 

1237 

1238 # Dict form is then queried to add defaults from setups.py. 

1239 if 'base' in p['setups']: 

1240 setups = setups_defaults[p['setups']['base'].lower()] 

1241 else: 

1242 setups = {} 

1243 

1244 # Override defaults with user-defined setups 

1245 if p['setups'] is not None: 

1246 setups.update(p['setups']) 

1247 

1248 for m in setups: 

1249 try: 

1250 special_setups.append(int(m)) 

1251 except ValueError: 

1252 pass 

1253 return setups, special_setups 

1254 

1255 def initialize(self, atoms): 

1256 """Initialize a VASP calculation 

1257 

1258 Constructs the POTCAR file (does not actually write it). 

1259 User should specify the PATH 

1260 to the pseudopotentials in VASP_PP_PATH environment variable 

1261 

1262 The pseudopotentials are expected to be in: 

1263 LDA: $VASP_PP_PATH/potpaw/ 

1264 PBE: $VASP_PP_PATH/potpaw_PBE/ 

1265 PW91: $VASP_PP_PATH/potpaw_GGA/ 

1266 

1267 if your pseudopotentials are somewhere else, or named 

1268 differently you may make symlinks at the paths above that 

1269 point to the right place. Alternatively, you may pass the full 

1270 name of a folder on the VASP_PP_PATH to the 'pp' parameter. 

1271 """ 

1272 

1273 self.check_xc() 

1274 self.atoms = atoms 

1275 self.all_symbols = atoms.get_chemical_symbols() 

1276 self.natoms = len(atoms) 

1277 

1278 self.spinpol = (atoms.get_initial_magnetic_moments().any() 

1279 or self.int_params['ispin'] == 2) 

1280 

1281 setups, special_setups = self._get_setups() 

1282 

1283 # Determine the number of atoms of each atomic species 

1284 # sorted after atomic species 

1285 symbols, symbolcount = count_symbols(atoms, exclude=special_setups) 

1286 self.sort, self.resort = self._make_sort(atoms, 

1287 special_setups=special_setups) 

1288 

1289 self.atoms_sorted = atoms[self.sort] 

1290 

1291 # Check if the necessary POTCAR files exists and 

1292 # create a list of their paths. 

1293 atomtypes = atoms.get_chemical_symbols() 

1294 self.symbol_count = [] 

1295 for m in special_setups: 

1296 self.symbol_count.append([atomtypes[m], 1]) 

1297 for m in symbols: 

1298 self.symbol_count.append([m, symbolcount[m]]) 

1299 

1300 # create pseudopotential list 

1301 self.ppp_list = self._build_pp_list(atoms, 

1302 setups=setups, 

1303 special_setups=special_setups) 

1304 

1305 self.converged = None 

1306 self.setups_changed = None 

1307 

1308 def default_nelect_from_ppp(self): 

1309 """ Get default number of electrons from ppp_list and symbol_count 

1310 

1311 "Default" here means that the resulting cell would be neutral. 

1312 """ 

1313 symbol_valences = [] 

1314 for filename in self.ppp_list: 

1315 with open_potcar(filename=filename) as ppp_file: 

1316 r = read_potcar_numbers_of_electrons(ppp_file) 

1317 symbol_valences.extend(r) 

1318 assert len(self.symbol_count) == len(symbol_valences) 

1319 default_nelect = 0 

1320 for ((symbol1, count), 

1321 (symbol2, valence)) in zip(self.symbol_count, symbol_valences): 

1322 assert symbol1 == symbol2 

1323 default_nelect += count * valence 

1324 return default_nelect 

1325 

1326 def write_input(self, atoms, directory='./'): 

1327 from ase.io.vasp import write_vasp 

1328 write_vasp(join(directory, 'POSCAR'), 

1329 self.atoms_sorted, 

1330 symbol_count=self.symbol_count, 

1331 ignore_constraints=self.input_params['ignore_constraints']) 

1332 self.write_incar(atoms, directory=directory) 

1333 self.write_potcar(directory=directory) 

1334 self.write_kpoints(atoms=atoms, directory=directory) 

1335 self.write_sort_file(directory=directory) 

1336 self.copy_vdw_kernel(directory=directory) 

1337 

1338 def copy_vdw_kernel(self, directory='./'): 

1339 """Method to copy the vdw_kernel.bindat file. 

1340 Set ASE_VASP_VDW environment variable to the vdw_kernel.bindat 

1341 folder location. Checks if LUSE_VDW is enabled, and if no location 

1342 for the vdW kernel is specified, a warning is issued.""" 

1343 

1344 vdw_env = 'ASE_VASP_VDW' 

1345 kernel = 'vdw_kernel.bindat' 

1346 dst = os.path.join(directory, kernel) 

1347 

1348 # No need to copy the file again 

1349 if isfile(dst): 

1350 return 

1351 

1352 if self.bool_params['luse_vdw']: 

1353 src = None 

1354 if vdw_env in os.environ: 

1355 src = os.path.join(os.environ[vdw_env], kernel) 

1356 

1357 if not src or not isfile(src): 

1358 warnings.warn( 

1359 ('vdW has been enabled, however no' 

1360 ' location for the {} file' 

1361 ' has been specified.' 

1362 ' Set {} environment variable to' 

1363 ' copy the vdW kernel.').format(kernel, vdw_env)) 

1364 else: 

1365 shutil.copyfile(src, dst) 

1366 

1367 def clean(self): 

1368 """Method which cleans up after a calculation. 

1369 

1370 The default files generated by Vasp will be deleted IF this 

1371 method is called. 

1372 

1373 """ 

1374 files = [ 

1375 'CHG', 'CHGCAR', 'POSCAR', 'INCAR', 'CONTCAR', 'DOSCAR', 

1376 'EIGENVAL', 'IBZKPT', 'KPOINTS', 'OSZICAR', 'OUTCAR', 'PCDAT', 

1377 'POTCAR', 'vasprun.xml', 'WAVECAR', 'XDATCAR', 'PROCAR', 

1378 'ase-sort.dat', 'LOCPOT', 'AECCAR0', 'AECCAR1', 'AECCAR2' 

1379 ] 

1380 for f in files: 

1381 try: 

1382 os.remove(f) 

1383 except OSError: 

1384 pass 

1385 

1386 def write_incar(self, atoms, directory='./', **kwargs): 

1387 """Writes the INCAR file.""" 

1388 p = self.input_params 

1389 # jrk 1/23/2015 I added this flag because this function has 

1390 # two places where magmoms get written. There is some 

1391 # complication when restarting that often leads to magmom 

1392 # getting written twice. this flag prevents that issue. 

1393 magmom_written = False 

1394 incar = open(join(directory, 'INCAR'), 'w') 

1395 incar.write('INCAR created by Atomic Simulation Environment\n') 

1396 for key, val in self.float_params.items(): 

1397 if key == 'nelect': 

1398 charge = p.get('charge') 

1399 # Handle deprecated net_charge parameter (remove at some point) 

1400 net_charge = p.get('net_charge') 

1401 if net_charge is not None: 

1402 warnings.warn( 

1403 '`net_charge`, which is given in units of ' 

1404 'the *negative* elementary charge (i.e., the opposite ' 

1405 'of what one normally calls charge) has been ' 

1406 'deprecated in favor of `charge`, which is given in ' 

1407 'units of the positive elementary charge as usual', 

1408 category=FutureWarning) 

1409 if charge is not None and charge != -net_charge: 

1410 raise ValueError( 

1411 "can't give both net_charge and charge") 

1412 charge = -net_charge 

1413 # We need to determine the nelect resulting from a given net 

1414 # charge in any case if it's != 0, but if nelect is 

1415 # additionally given explicitly, then we need to determine it 

1416 # even for net charge of 0 to check for conflicts 

1417 if charge is not None and (charge != 0 or val is not None): 

1418 default_nelect = self.default_nelect_from_ppp() 

1419 nelect_from_charge = default_nelect - charge 

1420 if val is not None and val != nelect_from_charge: 

1421 raise ValueError('incompatible input parameters: ' 

1422 'nelect=%s, but charge=%s ' 

1423 '(neutral nelect is %s)' % 

1424 (val, charge, default_nelect)) 

1425 val = nelect_from_charge 

1426 if val is not None: 

1427 incar.write(' %s = %5.6f\n' % (key.upper(), val)) 

1428 for key, val in self.exp_params.items(): 

1429 if val is not None: 

1430 incar.write(' %s = %5.2e\n' % (key.upper(), val)) 

1431 for key, val in self.string_params.items(): 

1432 if val is not None: 

1433 incar.write(' %s = %s\n' % (key.upper(), val)) 

1434 for key, val in self.int_params.items(): 

1435 if val is not None: 

1436 incar.write(' %s = %d\n' % (key.upper(), val)) 

1437 if key == 'ichain' and val > 0: 

1438 incar.write(' IBRION = 3\n POTIM = 0.0\n') 

1439 for key, val in self.int_params.items(): 

1440 if key == 'iopt' and val is None: 

1441 print('WARNING: optimization is ' 

1442 'set to LFBGS (IOPT = 1)') 

1443 incar.write(' IOPT = 1\n') 

1444 for key, val in self.exp_params.items(): 

1445 if key == 'ediffg' and val is None: 

1446 RuntimeError('Please set EDIFFG < 0') 

1447 

1448 for key, val in self.list_bool_params.items(): 

1449 if val is None: 

1450 pass 

1451 else: 

1452 incar.write(' %s = ' % key.upper()) 

1453 [incar.write('%s ' % _to_vasp_bool(x)) for x in val] 

1454 incar.write('\n') 

1455 

1456 for key, val in self.list_int_params.items(): 

1457 if val is None: 

1458 pass 

1459 elif key == 'ldaul' and (self.dict_params['ldau_luj'] is not None): 

1460 pass 

1461 else: 

1462 incar.write(' %s = ' % key.upper()) 

1463 [incar.write('%d ' % x) for x in val] 

1464 incar.write('\n') 

1465 

1466 for key, val in self.list_float_params.items(): 

1467 if val is None: 

1468 pass 

1469 elif ((key in ('ldauu', 'ldauj')) 

1470 and (self.dict_params['ldau_luj'] is not None)): 

1471 pass 

1472 elif key == 'magmom': 

1473 if not len(val) == len(atoms): 

1474 msg = ('Expected length of magmom tag to be' 

1475 ' {}, i.e. 1 value per atom, but got {}').format( 

1476 len(atoms), len(val)) 

1477 raise ValueError(msg) 

1478 

1479 # Check if user remembered to specify ispin 

1480 # note: we do not overwrite ispin if ispin=1 

1481 if not self.int_params['ispin']: 

1482 self.spinpol = True 

1483 incar.write(' ispin = 2\n'.upper()) 

1484 

1485 incar.write(' %s = ' % key.upper()) 

1486 magmom_written = True 

1487 # Work out compact a*x b*y notation and write in this form 

1488 # Assume 1 magmom per atom, ordered as our atoms object 

1489 val = np.array(val) 

1490 val = val[self.sort] # Order in VASP format 

1491 

1492 # Compactify the magmom list to symbol order 

1493 lst = [[1, val[0]]] 

1494 for n in range(1, len(val)): 

1495 if val[n] == val[n - 1]: 

1496 lst[-1][0] += 1 

1497 else: 

1498 lst.append([1, val[n]]) 

1499 incar.write(' '.join( 

1500 ['{:d}*{:.4f}'.format(mom[0], mom[1]) for mom in lst])) 

1501 incar.write('\n') 

1502 else: 

1503 incar.write(' %s = ' % key.upper()) 

1504 [incar.write('%.4f ' % x) for x in val] 

1505 incar.write('\n') 

1506 

1507 for key, val in self.bool_params.items(): 

1508 if val is not None: 

1509 incar.write(' %s = ' % key.upper()) 

1510 if val: 

1511 incar.write('.TRUE.\n') 

1512 else: 

1513 incar.write('.FALSE.\n') 

1514 for key, val in self.special_params.items(): 

1515 if val is not None: 

1516 incar.write(' %s = ' % key.upper()) 

1517 if key == 'lreal': 

1518 if isinstance(val, str): 

1519 incar.write(val + '\n') 

1520 elif isinstance(val, bool): 

1521 if val: 

1522 incar.write('.TRUE.\n') 

1523 else: 

1524 incar.write('.FALSE.\n') 

1525 for key, val in self.dict_params.items(): 

1526 if val is not None: 

1527 if key == 'ldau_luj': 

1528 # User didn't turn on LDAU tag. 

1529 # Only turn on if ldau is unspecified 

1530 if self.bool_params['ldau'] is None: 

1531 self.bool_params['ldau'] = True 

1532 # At this point we have already parsed our bool params 

1533 incar.write(' LDAU = .TRUE.\n') 

1534 llist = ulist = jlist = '' 

1535 for symbol in self.symbol_count: 

1536 # default: No +U 

1537 luj = val.get(symbol[0], {'L': -1, 'U': 0.0, 'J': 0.0}) 

1538 llist += ' %i' % luj['L'] 

1539 ulist += ' %.3f' % luj['U'] 

1540 jlist += ' %.3f' % luj['J'] 

1541 incar.write(' LDAUL =%s\n' % llist) 

1542 incar.write(' LDAUU =%s\n' % ulist) 

1543 incar.write(' LDAUJ =%s\n' % jlist) 

1544 

1545 if (self.spinpol and not magmom_written 

1546 # We don't want to write magmoms if they are all 0. 

1547 # but we could still be doing a spinpol calculation 

1548 and atoms.get_initial_magnetic_moments().any()): 

1549 if not self.int_params['ispin']: 

1550 incar.write(' ispin = 2\n'.upper()) 

1551 # Write out initial magnetic moments 

1552 magmom = atoms.get_initial_magnetic_moments()[self.sort] 

1553 # unpack magmom array if three components specified 

1554 if magmom.ndim > 1: 

1555 magmom = [item for sublist in magmom for item in sublist] 

1556 list = [[1, magmom[0]]] 

1557 for n in range(1, len(magmom)): 

1558 if magmom[n] == magmom[n - 1]: 

1559 list[-1][0] += 1 

1560 else: 

1561 list.append([1, magmom[n]]) 

1562 incar.write(' magmom = '.upper()) 

1563 [incar.write('%i*%.4f ' % (mom[0], mom[1])) for mom in list] 

1564 incar.write('\n') 

1565 

1566 # Custom key-value pairs, which receive no formatting 

1567 # Use the comment "# <Custom ASE key>" to denote such 

1568 # a custom key-value pair, as we cannot otherwise 

1569 # reliably and easily identify such non-standard entries 

1570 custom_kv_pairs = p.get('custom') 

1571 for key, value in custom_kv_pairs.items(): 

1572 incar.write(' {} = {} # <Custom ASE key>\n'.format( 

1573 key.upper(), value)) 

1574 incar.close() 

1575 

1576 def write_kpoints(self, atoms=None, directory='./', **kwargs): 

1577 """Writes the KPOINTS file.""" 

1578 

1579 if atoms is None: 

1580 atoms = self.atoms 

1581 

1582 # Don't write anything if KSPACING is being used 

1583 if self.float_params['kspacing'] is not None: 

1584 if self.float_params['kspacing'] > 0: 

1585 return 

1586 else: 

1587 raise ValueError("KSPACING value {0} is not allowable. " 

1588 "Please use None or a positive number." 

1589 "".format(self.float_params['kspacing'])) 

1590 

1591 p = self.input_params 

1592 with open(join(directory, 'KPOINTS'), 'w') as kpoints: 

1593 kpoints.write('KPOINTS created by Atomic Simulation Environment\n') 

1594 

1595 if isinstance(p['kpts'], dict): 

1596 p['kpts'] = kpts2ndarray(p['kpts'], atoms=atoms) 

1597 p['reciprocal'] = True 

1598 

1599 shape = np.array(p['kpts']).shape 

1600 

1601 # Wrap scalar in list if necessary 

1602 if shape == (): 

1603 p['kpts'] = [p['kpts']] 

1604 shape = (1, ) 

1605 

1606 if len(shape) == 1: 

1607 kpoints.write('0\n') 

1608 if shape == (1, ): 

1609 kpoints.write('Auto\n') 

1610 elif p['gamma']: 

1611 kpoints.write('Gamma\n') 

1612 else: 

1613 kpoints.write('Monkhorst-Pack\n') 

1614 [kpoints.write('%i ' % kpt) for kpt in p['kpts']] 

1615 kpoints.write('\n0 0 0\n') 

1616 elif len(shape) == 2: 

1617 kpoints.write('%i \n' % (len(p['kpts']))) 

1618 if p['reciprocal']: 

1619 kpoints.write('Reciprocal\n') 

1620 else: 

1621 kpoints.write('Cartesian\n') 

1622 for n in range(len(p['kpts'])): 

1623 [kpoints.write('%f ' % kpt) for kpt in p['kpts'][n]] 

1624 if shape[1] == 4: 

1625 kpoints.write('\n') 

1626 elif shape[1] == 3: 

1627 kpoints.write('1.0 \n') 

1628 

1629 def write_potcar(self, suffix="", directory='./'): 

1630 """Writes the POTCAR file.""" 

1631 

1632 with open(join(directory, 'POTCAR' + suffix), 'w') as potfile: 

1633 for filename in self.ppp_list: 

1634 with open_potcar(filename=filename) as ppp_file: 

1635 for line in ppp_file: 

1636 potfile.write(line) 

1637 

1638 def write_sort_file(self, directory='./'): 

1639 """Writes a sortings file. 

1640 

1641 This file contains information about how the atoms are sorted in 

1642 the first column and how they should be resorted in the second 

1643 column. It is used for restart purposes to get sorting right 

1644 when reading in an old calculation to ASE.""" 

1645 

1646 file = open(join(directory, 'ase-sort.dat'), 'w') 

1647 for n in range(len(self.sort)): 

1648 file.write('%5i %5i \n' % (self.sort[n], self.resort[n])) 

1649 

1650 # The below functions are used to restart a calculation 

1651 

1652 def read_incar(self, filename): 

1653 """Method that imports settings from INCAR file. 

1654 

1655 Typically named INCAR.""" 

1656 

1657 self.spinpol = False 

1658 with open(filename, 'r') as fd: 

1659 lines = fd.readlines() 

1660 

1661 for line in lines: 

1662 try: 

1663 # Make multiplication, comments, and parameters easier to spot 

1664 line = line.replace("*", " * ") 

1665 line = line.replace("=", " = ") 

1666 line = line.replace("#", "# ") 

1667 data = line.split() 

1668 # Skip empty and commented lines. 

1669 if len(data) == 0: 

1670 continue 

1671 elif data[0][0] in ['#', '!']: 

1672 continue 

1673 key = data[0].lower() 

1674 if '<Custom ASE key>' in line: 

1675 # This key was added with custom key-value pair formatting. 

1676 # Unconditionally add it, no type checking 

1677 # Get value between "=" and the comment, e.g. 

1678 # key = 1 2 3 # <Custom ASE key> 

1679 # value should be '1 2 3' 

1680 

1681 # Split at first occurence of "=" 

1682 value = line.split('=', 1)[1] 

1683 # First "#" denotes beginning of comment 

1684 # Add everything before comment as a string to custom dict 

1685 value = value.split('#', 1)[0].strip() 

1686 self.input_params['custom'][key] = value 

1687 elif key in float_keys: 

1688 self.float_params[key] = float(data[2]) 

1689 elif key in exp_keys: 

1690 self.exp_params[key] = float(data[2]) 

1691 elif key in string_keys: 

1692 self.string_params[key] = str(data[2]) 

1693 elif key in int_keys: 

1694 if key == 'ispin': 

1695 # JRK added. not sure why we would want to leave ispin 

1696 # out 

1697 self.int_params[key] = int(data[2]) 

1698 if int(data[2]) == 2: 

1699 self.spinpol = True 

1700 else: 

1701 self.int_params[key] = int(data[2]) 

1702 elif key in bool_keys: 

1703 if 'true' in data[2].lower(): 

1704 self.bool_params[key] = True 

1705 elif 'false' in data[2].lower(): 

1706 self.bool_params[key] = False 

1707 

1708 elif key in list_bool_keys: 

1709 self.list_bool_params[key] = [ 

1710 _from_vasp_bool(x) 

1711 for x in _args_without_comment(data[2:]) 

1712 ] 

1713 

1714 elif key in list_int_keys: 

1715 self.list_int_params[key] = [ 

1716 int(x) for x in _args_without_comment(data[2:]) 

1717 ] 

1718 

1719 elif key in list_float_keys: 

1720 if key == 'magmom': 

1721 lst = [] 

1722 i = 2 

1723 while i < len(data): 

1724 if data[i] in ["#", "!"]: 

1725 break 

1726 if data[i] == "*": 

1727 b = lst.pop() 

1728 i += 1 

1729 for j in range(int(b)): 

1730 lst.append(float(data[i])) 

1731 else: 

1732 lst.append(float(data[i])) 

1733 i += 1 

1734 self.list_float_params['magmom'] = lst 

1735 lst = np.array(lst) 

1736 if self.atoms is not None: 

1737 self.atoms.set_initial_magnetic_moments( 

1738 lst[self.resort]) 

1739 else: 

1740 data = _args_without_comment(data) 

1741 self.list_float_params[key] = [ 

1742 float(x) for x in data[2:] 

1743 ] 

1744 # elif key in list_keys: 

1745 # list = [] 

1746 # if key in ('dipol', 'eint', 'ferwe', 'ferdo', 

1747 # 'ropt', 'rwigs', 

1748 # 'ldauu', 'ldaul', 'ldauj', 'langevin_gamma'): 

1749 # for a in data[2:]: 

1750 # if a in ["!", "#"]: 

1751 # break 

1752 # list.append(float(a)) 

1753 # elif key in ('iband', 'kpuse', 'random_seed'): 

1754 # for a in data[2:]: 

1755 # if a in ["!", "#"]: 

1756 # break 

1757 # list.append(int(a)) 

1758 # self.list_params[key] = list 

1759 # if key == 'magmom': 

1760 # list = [] 

1761 # i = 2 

1762 # while i < len(data): 

1763 # if data[i] in ["#", "!"]: 

1764 # break 

1765 # if data[i] == "*": 

1766 # b = list.pop() 

1767 # i += 1 

1768 # for j in range(int(b)): 

1769 # list.append(float(data[i])) 

1770 # else: 

1771 # list.append(float(data[i])) 

1772 # i += 1 

1773 # self.list_params['magmom'] = list 

1774 # list = np.array(list) 

1775 # if self.atoms is not None: 

1776 # self.atoms.set_initial_magnetic_moments( 

1777 # list[self.resort]) 

1778 elif key in special_keys: 

1779 if key == 'lreal': 

1780 if 'true' in data[2].lower(): 

1781 self.special_params[key] = True 

1782 elif 'false' in data[2].lower(): 

1783 self.special_params[key] = False 

1784 else: 

1785 self.special_params[key] = data[2] 

1786 except KeyError: 

1787 raise IOError('Keyword "%s" in INCAR is' 

1788 'not known by calculator.' % key) 

1789 except IndexError: 

1790 raise IOError('Value missing for keyword "%s".' % key) 

1791 

1792 def read_kpoints(self, filename): 

1793 """Read kpoints file, typically named KPOINTS.""" 

1794 # If we used VASP builtin kspacing, 

1795 if self.float_params['kspacing'] is not None: 

1796 # Don't update kpts array 

1797 return 

1798 

1799 with open(filename, 'r') as fd: 

1800 lines = fd.readlines() 

1801 

1802 ktype = lines[2].split()[0].lower()[0] 

1803 if ktype in ['g', 'm', 'a']: 

1804 if ktype == 'g': 

1805 self.set(gamma=True) 

1806 kpts = np.array([int(lines[3].split()[i]) for i in range(3)]) 

1807 elif ktype == 'a': 

1808 kpts = np.array([int(lines[3].split()[i]) for i in range(1)]) 

1809 elif ktype == 'm': 

1810 kpts = np.array([int(lines[3].split()[i]) for i in range(3)]) 

1811 else: 

1812 if ktype in ['c', 'k']: 

1813 self.set(reciprocal=False) 

1814 else: 

1815 self.set(reciprocal=True) 

1816 kpts = np.array( 

1817 [list(map(float, line.split())) for line in lines[3:]]) 

1818 self.set(kpts=kpts) 

1819 

1820 def read_potcar(self, filename): 

1821 """ Read the pseudopotential XC functional from POTCAR file. 

1822 """ 

1823 

1824 # Search for key 'LEXCH' in POTCAR 

1825 xc_flag = None 

1826 with open(filename, 'r') as fd: 

1827 for line in fd: 

1828 key = line.split()[0].upper() 

1829 if key == 'LEXCH': 

1830 xc_flag = line.split()[-1].upper() 

1831 break 

1832 

1833 if xc_flag is None: 

1834 raise ValueError('LEXCH flag not found in POTCAR file.') 

1835 

1836 # Values of parameter LEXCH and corresponding XC-functional 

1837 xc_dict = {'PE': 'PBE', '91': 'PW91', 'CA': 'LDA'} 

1838 

1839 if xc_flag not in xc_dict.keys(): 

1840 raise ValueError('Unknown xc-functional flag found in POTCAR,' 

1841 ' LEXCH=%s' % xc_flag) 

1842 

1843 self.input_params['pp'] = xc_dict[xc_flag] 

1844 

1845 def todict(self): 

1846 """Returns a dictionary of all parameters 

1847 that can be used to construct a new calculator object""" 

1848 dict_list = [ 

1849 'float_params', 'exp_params', 'string_params', 'int_params', 

1850 'bool_params', 'list_bool_params', 'list_int_params', 

1851 'list_float_params', 'special_params', 'dict_params', 

1852 'input_params' 

1853 ] 

1854 dct = {} 

1855 for item in dict_list: 

1856 dct.update(getattr(self, item)) 

1857 dct = {key: value for key, value in dct.items() if value is not None} 

1858 return dct 

1859 

1860 

1861def _args_without_comment(data, marks=['!', '#']): 

1862 """Check split arguments list for a comment, return data up to marker 

1863 

1864 INCAR reader splits list arguments on spaces and leaves comment markers as 

1865 individual items. This function returns only the data portion of the list. 

1866 

1867 """ 

1868 comment_locs = [data.index(mark) for mark in marks if mark in data] 

1869 if comment_locs == []: 

1870 return data 

1871 else: 

1872 return data[:min(comment_locs)] 

1873 

1874 

1875def _from_vasp_bool(x): 

1876 """Cast vasp boolean to Python bool 

1877 

1878 VASP files sometimes use T or F as shorthand for the preferred Boolean 

1879 notation .TRUE. or .FALSE. As capitalisation is pretty inconsistent in 

1880 practice, we allow all cases to be cast to a Python bool. 

1881 

1882 """ 

1883 assert isinstance(x, str) 

1884 if x.lower() == '.true.' or x.lower() == 't': 

1885 return True 

1886 elif x.lower() == '.false.' or x.lower() == 'f': 

1887 return False 

1888 else: 

1889 raise ValueError('Value "%s" not recognized as bool' % x) 

1890 

1891 

1892def _to_vasp_bool(x): 

1893 """Convert Python boolean to string for VASP input 

1894 

1895 In case the value was modified to a string already, appropriate strings 

1896 will also be accepted and cast to a standard .TRUE. / .FALSE. format. 

1897 

1898 """ 

1899 if isinstance(x, str): 

1900 if x.lower() in ('.true.', 't'): 

1901 x = True 

1902 elif x.lower() in ('.false.', 'f'): 

1903 x = False 

1904 else: 

1905 raise ValueError('"%s" not recognised as VASP Boolean') 

1906 assert isinstance(x, bool) 

1907 if x: 

1908 return '.TRUE.' 

1909 else: 

1910 return '.FALSE.' 

1911 

1912 

1913def open_potcar(filename): 

1914 """ Open POTCAR file with transparent decompression if it's an archive (.Z) 

1915 """ 

1916 import gzip 

1917 if filename.endswith('R'): 

1918 return open(filename, 'r') 

1919 elif filename.endswith('.Z'): 

1920 return gzip.open(filename) 

1921 else: 

1922 raise ValueError('Invalid POTCAR filename: "%s"' % filename) 

1923 

1924 

1925def read_potcar_numbers_of_electrons(file_obj): 

1926 """ Read list of tuples (atomic symbol, number of valence electrons) 

1927 for each atomtype from a POTCAR file.""" 

1928 nelect = [] 

1929 lines = file_obj.readlines() 

1930 for n, line in enumerate(lines): 

1931 if 'TITEL' in line: 

1932 symbol = line.split('=')[1].split()[1].split('_')[0].strip() 

1933 valence = float( 

1934 lines[n + 4].split(';')[1].split('=')[1].split()[0].strip()) 

1935 nelect.append((symbol, valence)) 

1936 return nelect 

1937 

1938 

1939def count_symbols(atoms, exclude=()): 

1940 """Count symbols in atoms object, excluding a set of indices 

1941  

1942 Parameters: 

1943 atoms: Atoms object to be grouped 

1944 exclude: List of indices to be excluded from the counting 

1945  

1946 Returns: 

1947 Tuple of (symbols, symbolcount) 

1948 symbols: The unique symbols in the included list 

1949 symbolscount: Count of symbols in the included list 

1950 

1951 Example: 

1952 

1953 >>> from ase.build import bulk 

1954 >>> atoms = bulk('NaCl', crystalstructure='rocksalt', a=4.1, cubic=True) 

1955 >>> count_symbols(atoms) 

1956 (['Na', 'Cl'], {'Na': 4, 'Cl': 4}) 

1957 >>> count_symbols(atoms, exclude=(1, 2, 3)) 

1958 (['Na', 'Cl'], {'Na': 3, 'Cl': 2}) 

1959 """ 

1960 symbols = [] 

1961 symbolcount = {} 

1962 for m, symbol in enumerate(atoms.symbols): 

1963 if m in exclude: 

1964 continue 

1965 if symbol not in symbols: 

1966 symbols.append(symbol) 

1967 symbolcount[symbol] = 1 

1968 else: 

1969 symbolcount[symbol] += 1 

1970 return symbols, symbolcount