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 'nupdown', # fix spin moment to specified value 

230] 

231 

232exp_keys = [ 

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

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

235 'symprec', # precession in symmetry routines 

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

237 # group at UT Austin 

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

239] 

240 

241string_keys = [ 

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

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

244 'metagga', # 

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

246 'system', # name of System 

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

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

249 'localized_basis', # Basis to use in CRPA 

250 'proutine', # Select profiling routine 

251] 

252 

253int_keys = [ 

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

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

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

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

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

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

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

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

262 'ispin', # spin-polarized calculation 

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

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

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

266 'kpar', # k-point parallelization paramater 

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

268 # written 

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

270 'lmaxmix', # 

271 'lorbit', # create PROOUT 

272 'maxmix', # 

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

274 'ngxf', # FFT mesh for charges x 

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

276 'ngyf', # FFT mesh for charges y 

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

278 'ngzf', # FFT mesh for charges z 

279 'nbands', # Number of bands 

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

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

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

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

284 'nelmin', 

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

286 # finite differences 

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

288 # nkredx=nkredy=nkredz 

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

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

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

292 'nomega', # number of frequency points 

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

294 'npar', # parallelization over bands 

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

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

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 # (Possibly Depricated) Number of groups in real time for 

326 # response function calc. 

327 'taupar', 

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

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

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

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

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

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

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

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

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

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

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

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

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

341 'ibse', # Type of BSE calculation 

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

343 'naturalo', # Use NATURALO (?) 

344 'nbandsexact', # Undocumented parameter 

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

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

347 'omegagrid', # Undocumented parameter 

348 'telescope', # Undocumented parameter 

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

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

351 'dim', # Undocumented parameter 

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

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

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

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

356 'lmaxmp2', # Undocumented parameter 

357 'switch', # Undocumented dimer parameter 

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

359 'engine', # Undocumented dimer parameter 

360 'restartcg', # Undocumented dimer parameter 

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

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

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

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

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

366 'hills_maxstride', # Undocumented metadynamics parameter 

367 'dvvehistory', # Undocumented parameter 

368 'ipead', # Undocumented parameter 

369 'ngaus', # Undocumented charge fitting parameter 

370 'exxoep', # Undocumented HF parameter 

371 'fourorbit', # Undocumented HF parameter 

372 'model_gw', # Undocumented HF parameter 

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

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

375 'lmaxfockae', # Undocumented HF parameter 

376 'nmaxfockae', # Undocumented HF parameter 

377 'nblock_fock', # Undocumented HF parameter 

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

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

380 'mremove', # Undocumented mixing parameter 

381 'inimix', # Undocumented mixing parameter 

382 'mixpre', # Undocumented mixing parameter 

383 'nelmall', # Undocumented parameter 

384 'nblock', # How frequently to write data 

385 'kblock', # How frequently to write data 

386 'npaco', # Undocumented pair correlation function parameter 

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

388 'irestart', # Undocumented parameter 

389 'nreboot', # Undocumented parameter 

390 'nmin', # Undocumented parameter 

391 'nlspline', # Undocumented parameter 

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

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

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

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

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

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

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

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

400 'nbands_out', # Undocumented QP parameter 

401 'kpts_out', # Undocumented QP parameter 

402 'isp_out', # Undocumented QP parameter 

403 'nomega_out', # Undocumented QP parameter 

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

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

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

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

408 'ncore_in_image1', # Undocumented parameter 

409 'kimages', # Undocumented parameter 

410 'ncores_per_band', # Undocumented parameter 

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

412 'ncrpalow', # Undocumented CRPA parameter 

413 'ncrpahigh', # Undocumented CRPA parameter 

414 'nwlow', # Undocumented parameter 

415 'nwhigh', # Undocumented parameter 

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

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

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

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

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

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

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

423] 

424 

425bool_keys = [ 

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

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

428 # centred at the $\Gamma$ 

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

430 # (KGAMMA=.TRUE.) 

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

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

433 # VASP.5.X) 

434 'lasync', # overlap communcation with calculations 

435 'lcharg', # 

436 'lcorr', # Harris-correction to forces 

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

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

439 'ldipol', # potential correction mode 

440 'lelf', # create ELFCAR 

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

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

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

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

445 # density 

446 'lplane', # parallelisation over the FFT grid 

447 'lscalapack', # switch off scaLAPACK 

448 'lscalu', # switch of LU decomposition 

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

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

451 'lthomas', # 

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

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

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

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

456 'lwave', # 

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

458 # group at UT Austin 

459 'lclimb', # Turn on CI-NEB 

460 'ltangentold', # Old central difference tangent 

461 'ldneb', # Turn on modified double nudging 

462 'lnebcell', # Turn on SS-NEB 

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

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

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

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

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

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

469 # tensors (vasp 5.2) 

470 'lvdw', # Turns on dispersion correction 

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

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

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

474 # polarizability 

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

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

477 'lsorbit', # Enable spin-orbit coupling 

478 'lsol', # turn on solvation for Vaspsol 

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

480 'interactive', # Enables interactive calculation for VaspInteractive 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

511 'lmixtau', # Undocumented MetaGGA parameter 

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

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

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

515 'lnabla', # Undocumented parameter 

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

517 'lvel', # Undocumented parameter 

518 'lrpaforce', # Calculate RPA forces 

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

520 'ladder', # Use ladder diagrams 

521 'lfxc', # Use approximate ladder diagrams 

522 'lrsrpa', # Undocumented parameter 

523 'lsingles', # Calculate HF singles 

524 'lfermigw', # Iterate Fermi level 

525 'ltcte', # Undocumented parameter 

526 'ltete', # Undocumented parameter 

527 'ltriplet', # Undocumented parameter 

528 'lfxceps', # Undocumented parameter 

529 'lfxheg', # Undocumented parameter 

530 'l2order', # Undocumented parameter 

531 'lmp2lt', # Undocumented parameter 

532 'lgwlf', # Undocumented parameter 

533 'lusew', # Undocumented parameter 

534 'selfenergy', # Undocumented parameter 

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

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

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

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

539 'fletcher_reeves', # Undocumented dimer parameter 

540 'lidm_selective', # Undocumented dimer parameter 

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

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

543 'dvvminus', # Undocumented parameter 

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

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

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

547 'lchgfit', # Turn on charge fitting 

548 'lgausrc', # Undocumented charge fitting parameter 

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

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

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

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

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

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

555 'shiftred', # Undocumented HF parameter 

556 'hfkident', # Undocumented HF parameter 

557 'oddonly', # Undocumented HF parameter 

558 'evenonly', # Undocumented HF parameter 

559 'lfockaedft', # Undocumented HF parameter 

560 'lsubrot', # Enable subspace rotation diagonalization 

561 'mixfirst', # Mix before diagonalization 

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

563 'lcompat', # Enable "full compatibility" 

564 'lmusic', # "Joke" parameter 

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

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

567 'lorbitalreal', # Undocumented parameter 

568 'lmetagga', # Undocumented parameter 

569 'lspiral', # Undocumented parameter 

570 'lzeroz', # Undocumented parameter 

571 'lmono', # Enable "monopole" corrections 

572 'lrelcore', # Perform relaxed core calculation 

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

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

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

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

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

578 'lrelvol', # Undocumented classical vdW parameter 

579 'lj_only', # Undocumented classical vdW parameter 

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

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

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

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

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

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

586 'lvdw_relvolone', # Undocumented classical vdW parameter 

587 'lberry', # Enable Berry-phase calculation 

588 'lpade_fit', # Undocumented QP parameter 

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

590 'l_wr_moments', # Undocumented parameter 

591 'l_wr_density', # Undocumented parameter 

592 'lkotani', # Undocumented parameter 

593 'ldyson', # Undocumented parameter 

594 'laddherm', # Undocumented parameter 

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

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

597 'ldisentangle', # Disentangle bands in CRPA 

598 'lweighted', # "Weighted" CRPA approach 

599 'luseorth_lcaos', # Use orthogonalized LCAOs in CRPA 

600 'lfrpa', # Use full RPA in CRPA 

601 'lregularize', # Regularize projectors in CRPA 

602 'ldrude', # Include Drude term in CRPA 

603 'ldmatrix', # Undocumented parameter 

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

605 'lhyperfine', # Enable Hyperfine calculation 

606 'lwannier', # Enable Wannier interface 

607 'localize', # Undocumented Wannier parameter 

608 'lintpol_wpot', # Interpolate WPOT for Wannier 

609 'lintpol_orb', # Interpolate orbitals for Wannier 

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

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

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

613 'lintpol_velocity', # Interpolate electron velocity for Wannier 

614 'lintpol_conductivity', # Interpolate conductivity for Wannier 

615 'lwannierinterpol', # Undocumented Wannier parameter 

616 'wanproj', # Undocumented Wannier parameter 

617 'lorbmom', # Undocumented LDA+U parameter 

618 'lwannier90_run', # Undocumented WANNIER90 parameter 

619 'lwrite_wanproj', # Write UWAN files for WANNIER90 

620 'lwrite_unk', # Write UNK files for WANNIER90 

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

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

623 'lrhfatm', # Undocumented HF parameter 

624 'lvpot', # Calculate unscreened potential 

625 'lwpot', # Calculate screened potential 

626 'lwswq', # Undocumented parameter 

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

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

629 'qdo_ins', # Find instanton 

630 'qdo_pre', # Calculate prefactor (instanton) 

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

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

633 'lnbo', # Enable NBO analysis 

634] 

635 

636list_int_keys = [ 

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

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

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

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

641 # (Bucko) 

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

643 'auger_bmax_eeh', # 4 ints | calculations 

644 'auger_bmin_ehh', # 4 ints | 

645 'auger_bmax_ehh', # 4 ints | 

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

647 'kpoint_bse', # 4 ints | Undocumented parameter 

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

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

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

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

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

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

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

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

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

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

658] 

659 

660list_bool_keys = [ 

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

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

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

664] 

665 

666list_float_keys = [ 

667 'dipol', # center of cell for dipol 

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

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

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

671 'magmom', # initial magnetic moments 

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

673 'rwigs', # Wigner-Seitz radii 

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

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

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

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

678 # when a calculation is set up 

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

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

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

682 # (DFT-TS) 

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

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

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

686 # (DFT-TS) 

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

688 # species (DFT-TS) 

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

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

691 'auger_emax_eeh', # 4 floats | calculations 

692 'auger_emin_ehh', # 4 floats | 

693 'auger_emax_ehh', # 4 floats | 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

726 'qspiral', # 3 floats | Undocumented parameter 

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

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

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

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

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

732 'ofield_k', # 3 floats | Undocumented parameter 

733 'paripot', # ? floats | Undocumented parameter 

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

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

736] 

737 

738special_keys = [ 

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

740] 

741 

742dict_keys = [ 

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

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

745] 

746 

747keys: List[str] = [ 

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

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

750 # 'WEIMIN, EBREAK, DEPER special control tags 

751] 

752 

753 

754class GenerateVaspInput: 

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

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

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

758 xc_defaults = { 

759 'lda': { 

760 'pp': 'LDA' 

761 }, 

762 # GGAs 

763 'blyp': { # https://www.vasp.at/forum/viewtopic.php?p=17234 

764 'pp': 'PBE', 

765 'gga': 'B5', 

766 'aldax': 1.00, 

767 'aggax': 1.00, 

768 'aggac': 1.00, 

769 'aldac': 0.00 

770 }, 

771 'pw91': { 

772 'pp': 'PW91', 

773 'gga': '91' 

774 }, 

775 'pbe': { 

776 'pp': 'PBE', 

777 'gga': 'PE' 

778 }, 

779 'pbesol': { 

780 'gga': 'PS' 

781 }, 

782 'revpbe': { 

783 'gga': 'RE' 

784 }, 

785 'rpbe': { 

786 'gga': 'RP' 

787 }, 

788 'am05': { 

789 'gga': 'AM' 

790 }, 

791 # Meta-GGAs 

792 'tpss': { 

793 'metagga': 'TPSS' 

794 }, 

795 'revtpss': { 

796 'metagga': 'RTPSS' 

797 }, 

798 'm06l': { 

799 'metagga': 'M06L' 

800 }, 

801 'ms0': { 

802 'metagga': 'MS0' 

803 }, 

804 'ms1': { 

805 'metagga': 'MS1' 

806 }, 

807 'ms2': { 

808 'metagga': 'MS2' 

809 }, 

810 'scan': { 

811 'metagga': 'SCAN' 

812 }, 

813 'rscan': { 

814 'metagga': 'RSCAN' 

815 }, 

816 'r2scan': { 

817 'metagga': 'R2SCAN' 

818 }, 

819 'scan-rvv10': { 

820 'metagga': 'SCAN', 

821 'luse_vdw': True, 

822 'bparam': 15.7 

823 }, 

824 'mbj': { 

825 # Modified Becke-Johnson 

826 'metagga': 'MBJ', 

827 }, 

828 'tb09': { 

829 # Alias for MBJ 

830 'metagga': 'MBJ', 

831 }, 

832 # vdW-DFs 

833 'vdw-df': { 

834 'gga': 'RE', 

835 'luse_vdw': True, 

836 'aggac': 0. 

837 }, 

838 'vdw-df-cx': { 

839 'gga': 'CX', 

840 'luse_vdw': True, 

841 'aggac': 0. 

842 }, 

843 'vdw-df-cx0p': { 

844 'gga': 'CX', 

845 'luse_vdw': True, 

846 'aggac': 0., 

847 'lhfcalc': True, 

848 'aexx': 0.2, 

849 'aggax': 0.8 

850 }, 

851 'optpbe-vdw': { 

852 'gga': 'OR', 

853 'luse_vdw': True, 

854 'aggac': 0.0 

855 }, 

856 'optb88-vdw': { 

857 'gga': 'BO', 

858 'luse_vdw': True, 

859 'aggac': 0.0, 

860 'param1': 1.1 / 6.0, 

861 'param2': 0.22 

862 }, 

863 'optb86b-vdw': { 

864 'gga': 'MK', 

865 'luse_vdw': True, 

866 'aggac': 0.0, 

867 'param1': 0.1234, 

868 'param2': 1.0 

869 }, 

870 'vdw-df2': { 

871 'gga': 'ML', 

872 'luse_vdw': True, 

873 'aggac': 0.0, 

874 'zab_vdw': -1.8867 

875 }, 

876 'rev-vdw-df2': { 

877 'gga': 'MK', 

878 'luse_vdw': True, 

879 'param1': 0.1234, 

880 'param2': 0.711357, 

881 'zab_vdw': -1.8867, 

882 'aggac': 0.0 

883 }, 

884 'beef-vdw': { 

885 'gga': 'BF', 

886 'luse_vdw': True, 

887 'zab_vdw': -1.8867 

888 }, 

889 # Hartree-Fock and hybrids 

890 'hf': { 

891 'lhfcalc': True, 

892 'aexx': 1.0, 

893 'aldac': 0.0, 

894 'aggac': 0.0 

895 }, 

896 'b3lyp': { 

897 'gga': 'B3', 

898 'lhfcalc': True, 

899 'aexx': 0.2, 

900 'aggax': 0.72, 

901 'aggac': 0.81, 

902 'aldac': 0.19 

903 }, 

904 'pbe0': { 

905 'gga': 'PE', 

906 'lhfcalc': True 

907 }, 

908 'hse03': { 

909 'gga': 'PE', 

910 'lhfcalc': True, 

911 'hfscreen': 0.3 

912 }, 

913 'hse06': { 

914 'gga': 'PE', 

915 'lhfcalc': True, 

916 'hfscreen': 0.2 

917 }, 

918 'hsesol': { 

919 'gga': 'PS', 

920 'lhfcalc': True, 

921 'hfscreen': 0.2 

922 }, 

923 # MN-VFM functionals 

924 'sogga': { 

925 'gga': 'SA' 

926 }, 

927 'sogga11': { 

928 'gga': 'S1' 

929 }, 

930 'sogga11-x': { 

931 'gga': 'SX', 

932 'lhfcalc': True, 

933 'aexx': 0.401 

934 }, 

935 'n12': { 

936 'gga': 'N2' 

937 }, 

938 'n12-sx': { 

939 'gga': 'NX', 

940 'lhfcalc': True, 

941 'lhfscreen': 0.2 

942 }, 

943 'mn12l': { 

944 'metagga': 'MN12L' 

945 }, 

946 'gam': { 

947 'gga': 'GA' 

948 }, 

949 'mn15l': { 

950 'metagga': 'MN15L' 

951 }, 

952 'hle17': { 

953 'metagga': 'HLE17' 

954 }, 

955 'revm06l': { 

956 'metagga': 'revM06L' 

957 }, 

958 'm06sx': { 

959 'metagga': 'M06SX', 

960 'lhfcalc': True, 

961 'hfscreen': 0.189, 

962 'aexx': 0.335 

963 } 

964 } 

965 

966 # environment variable for PP paths 

967 VASP_PP_PATH = 'VASP_PP_PATH' 

968 

969 def __init__(self, restart=None): 

970 self.float_params = {} 

971 self.exp_params = {} 

972 self.string_params = {} 

973 self.int_params = {} 

974 self.bool_params = {} 

975 self.list_bool_params = {} 

976 self.list_int_params = {} 

977 self.list_float_params = {} 

978 self.special_params = {} 

979 self.dict_params = {} 

980 for key in float_keys: 

981 self.float_params[key] = None 

982 for key in exp_keys: 

983 self.exp_params[key] = None 

984 for key in string_keys: 

985 self.string_params[key] = None 

986 for key in int_keys: 

987 self.int_params[key] = None 

988 for key in bool_keys: 

989 self.bool_params[key] = None 

990 for key in list_bool_keys: 

991 self.list_bool_params[key] = None 

992 for key in list_int_keys: 

993 self.list_int_params[key] = None 

994 for key in list_float_keys: 

995 self.list_float_params[key] = None 

996 for key in special_keys: 

997 self.special_params[key] = None 

998 for key in dict_keys: 

999 self.dict_params[key] = None 

1000 

1001 # Initialize internal dictionary of input parameters which are 

1002 # not regular VASP keys 

1003 self.input_params = { 

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

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

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

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

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

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

1010 'gamma': False, 

1011 # number of points between points in band structures: 

1012 'kpts_nintersections': None, 

1013 # Option to write explicit k-points in units 

1014 # of reciprocal lattice vectors: 

1015 'reciprocal': False, 

1016 # Switch to disable writing constraints to POSCAR 

1017 'ignore_constraints': False, 

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

1019 'charge': None, 

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

1021 # with the sign flipped 

1022 'net_charge': None, 

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

1024 'custom': {}, 

1025 } 

1026 

1027 def set_xc_params(self, xc): 

1028 """Set parameters corresponding to XC functional""" 

1029 xc = xc.lower() 

1030 if xc is None: 

1031 pass 

1032 elif xc not in self.xc_defaults: 

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

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

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

1036 else: 

1037 # XC defaults to PBE pseudopotentials 

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

1039 self.set(pp='PBE') 

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

1041 

1042 def set(self, **kwargs): 

1043 

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

1045 and ('ldau_luj' in kwargs)): 

1046 raise NotImplementedError( 

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

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

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

1050 'chemical species in the atoms object. ' 

1051 'For example for a water molecule:' 

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

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

1054 

1055 if 'xc' in kwargs: 

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

1057 for key in kwargs: 

1058 if key in self.float_params: 

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

1060 elif key in self.exp_params: 

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

1062 elif key in self.string_params: 

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

1064 elif key in self.int_params: 

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

1066 elif key in self.bool_params: 

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

1068 elif key in self.list_bool_params: 

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

1070 elif key in self.list_int_params: 

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

1072 elif key in self.list_float_params: 

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

1074 elif key in self.special_params: 

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

1076 elif key in self.dict_params: 

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

1078 elif key in self.input_params: 

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

1080 else: 

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

1082 

1083 def check_xc(self): 

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

1085 

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

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

1088 """ 

1089 

1090 p = self.input_params 

1091 

1092 # There is no way to correctly guess the desired 

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

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

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

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

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

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

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

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

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

1102 else: 

1103 raise NotImplementedError( 

1104 "Unable to guess the desired set of pseudopotential" 

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

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

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

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

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

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

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

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

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

1114 "accepted.\n") 

1115 

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

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

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

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

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

1121 "really what you intended!" 

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

1123 

1124 def _make_sort( 

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

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

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

1128 

1129 # Create sorting list 

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

1131 srt.extend(special_setups) 

1132 

1133 for symbol in symbols: 

1134 for m, atom in enumerate(atoms): 

1135 if m in special_setups: 

1136 continue 

1137 if atom.symbol == symbol: 

1138 srt.append(m) 

1139 # Create the resorting list 

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

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

1142 resrt[srt[n]] = n 

1143 return srt, resrt 

1144 

1145 def _build_pp_list(self, 

1146 atoms, 

1147 setups=None, 

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

1149 """Build the pseudopotential lists""" 

1150 

1151 p = self.input_params 

1152 

1153 if setups is None: 

1154 setups, special_setups = self._get_setups() 

1155 

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

1157 

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

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

1160 ('pbe', 'potpaw_PBE')): 

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

1162 break 

1163 else: 

1164 pp_folder = p['pp'] 

1165 

1166 if self.VASP_PP_PATH in os.environ: 

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

1168 else: 

1169 pppaths = [] 

1170 ppp_list = [] 

1171 # Setting the pseudopotentials, first special setups and 

1172 # then according to symbols 

1173 for m in special_setups: 

1174 if m in setups: 

1175 special_setup_index = m 

1176 elif str(m) in setups: 

1177 special_setup_index = str(m) # type: ignore 

1178 else: 

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

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

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

1182 for path in pppaths: 

1183 filename = join(path, potcar) 

1184 

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

1186 ppp_list.append(filename) 

1187 break 

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

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

1190 break 

1191 else: 

1192 symbol = atoms.symbols[m] 

1193 msg = """Looking for {}. 

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

1195 potcar, symbol, setups[special_setup_index]) 

1196 raise RuntimeError(msg) 

1197 

1198 for symbol in symbols: 

1199 try: 

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

1201 except (TypeError, KeyError): 

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

1203 for path in pppaths: 

1204 filename = join(path, potcar) 

1205 

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

1207 ppp_list.append(filename) 

1208 break 

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

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

1211 break 

1212 else: 

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

1214 The pseudopotentials are expected to be in: 

1215 LDA: $VASP_PP_PATH/potpaw/ 

1216 PBE: $VASP_PP_PATH/potpaw_PBE/ 

1217 PW91: $VASP_PP_PATH/potpaw_GGA/ 

1218 

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

1220 raise RuntimeError(msg) 

1221 return ppp_list 

1222 

1223 def _get_setups(self): 

1224 p = self.input_params 

1225 

1226 special_setups = [] 

1227 

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

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

1230 # 

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

1232 # 

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

1234 # 

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

1236 # 

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

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

1239 # folder, respectively. 

1240 

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

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

1243 setups_defaults = get_default_setups() 

1244 

1245 # Default to minimal basis 

1246 if p['setups'] is None: 

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

1248 

1249 # String shortcuts are initialised to dict form 

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

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

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

1253 

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

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

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

1257 else: 

1258 setups = {} 

1259 

1260 # Override defaults with user-defined setups 

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

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

1263 

1264 for m in setups: 

1265 try: 

1266 special_setups.append(int(m)) 

1267 except ValueError: 

1268 pass 

1269 return setups, special_setups 

1270 

1271 def initialize(self, atoms): 

1272 """Initialize a VASP calculation 

1273 

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

1275 User should specify the PATH 

1276 to the pseudopotentials in VASP_PP_PATH environment variable 

1277 

1278 The pseudopotentials are expected to be in: 

1279 LDA: $VASP_PP_PATH/potpaw/ 

1280 PBE: $VASP_PP_PATH/potpaw_PBE/ 

1281 PW91: $VASP_PP_PATH/potpaw_GGA/ 

1282 

1283 if your pseudopotentials are somewhere else, or named 

1284 differently you may make symlinks at the paths above that 

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

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

1287 """ 

1288 

1289 self.check_xc() 

1290 self.atoms = atoms 

1291 self.all_symbols = atoms.get_chemical_symbols() 

1292 self.natoms = len(atoms) 

1293 

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

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

1296 

1297 setups, special_setups = self._get_setups() 

1298 

1299 # Determine the number of atoms of each atomic species 

1300 # sorted after atomic species 

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

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

1303 special_setups=special_setups) 

1304 

1305 self.atoms_sorted = atoms[self.sort] 

1306 

1307 # Check if the necessary POTCAR files exists and 

1308 # create a list of their paths. 

1309 atomtypes = atoms.get_chemical_symbols() 

1310 self.symbol_count = [] 

1311 for m in special_setups: 

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

1313 for m in symbols: 

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

1315 

1316 # create pseudopotential list 

1317 self.ppp_list = self._build_pp_list(atoms, 

1318 setups=setups, 

1319 special_setups=special_setups) 

1320 

1321 self.converged = None 

1322 self.setups_changed = None 

1323 

1324 def default_nelect_from_ppp(self): 

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

1326 

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

1328 """ 

1329 symbol_valences = [] 

1330 for filename in self.ppp_list: 

1331 with open_potcar(filename=filename) as ppp_file: 

1332 r = read_potcar_numbers_of_electrons(ppp_file) 

1333 symbol_valences.extend(r) 

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

1335 default_nelect = 0 

1336 for ((symbol1, count), 

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

1338 assert symbol1 == symbol2 

1339 default_nelect += count * valence 

1340 return default_nelect 

1341 

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

1343 from ase.io.vasp import write_vasp 

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

1345 self.atoms_sorted, 

1346 symbol_count=self.symbol_count, 

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

1348 self.write_incar(atoms, directory=directory) 

1349 self.write_potcar(directory=directory) 

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

1351 self.write_sort_file(directory=directory) 

1352 self.copy_vdw_kernel(directory=directory) 

1353 

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

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

1356 Set ASE_VASP_VDW environment variable to the vdw_kernel.bindat 

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

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

1359 

1360 vdw_env = 'ASE_VASP_VDW' 

1361 kernel = 'vdw_kernel.bindat' 

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

1363 

1364 # No need to copy the file again 

1365 if isfile(dst): 

1366 return 

1367 

1368 if self.bool_params['luse_vdw']: 

1369 src = None 

1370 if vdw_env in os.environ: 

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

1372 

1373 if not src or not isfile(src): 

1374 warnings.warn( 

1375 ('vdW has been enabled, however no' 

1376 ' location for the {} file' 

1377 ' has been specified.' 

1378 ' Set {} environment variable to' 

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

1380 else: 

1381 shutil.copyfile(src, dst) 

1382 

1383 def clean(self): 

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

1385 

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

1387 method is called. 

1388 

1389 """ 

1390 files = [ 

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

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

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

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

1395 ] 

1396 for f in files: 

1397 try: 

1398 os.remove(f) 

1399 except OSError: 

1400 pass 

1401 

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

1403 """Writes the INCAR file.""" 

1404 p = self.input_params 

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

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

1407 # complication when restarting that often leads to magmom 

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

1409 magmom_written = False 

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

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

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

1413 if key == 'nelect': 

1414 charge = p.get('charge') 

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

1416 net_charge = p.get('net_charge') 

1417 if net_charge is not None: 

1418 warnings.warn( 

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

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

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

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

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

1424 category=FutureWarning) 

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

1426 raise ValueError( 

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

1428 charge = -net_charge 

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

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

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

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

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

1434 default_nelect = self.default_nelect_from_ppp() 

1435 nelect_from_charge = default_nelect - charge 

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

1437 raise ValueError('incompatible input parameters: ' 

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

1439 '(neutral nelect is %s)' % 

1440 (val, charge, default_nelect)) 

1441 val = nelect_from_charge 

1442 if val is not None: 

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

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

1445 if val is not None: 

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

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

1448 if val is not None: 

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

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

1451 if val is not None: 

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

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

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

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

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

1457 print('WARNING: optimization is ' 

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

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

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

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

1462 RuntimeError('Please set EDIFFG < 0') 

1463 

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

1465 if val is None: 

1466 pass 

1467 else: 

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

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

1470 incar.write('\n') 

1471 

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

1473 if val is None: 

1474 pass 

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

1476 pass 

1477 else: 

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

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

1480 incar.write('\n') 

1481 

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

1483 if val is None: 

1484 pass 

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

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

1487 pass 

1488 elif key == 'magmom': 

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

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

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

1492 len(atoms), len(val)) 

1493 raise ValueError(msg) 

1494 

1495 # Check if user remembered to specify ispin 

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

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

1498 self.spinpol = True 

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

1500 

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

1502 magmom_written = True 

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

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

1505 val = np.array(val) 

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

1507 

1508 # Compactify the magmom list to symbol order 

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

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

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

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

1513 else: 

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

1515 incar.write(' '.join( 

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

1517 incar.write('\n') 

1518 else: 

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

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

1521 incar.write('\n') 

1522 

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

1524 if val is not None: 

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

1526 if val: 

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

1528 else: 

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

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

1531 if val is not None: 

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

1533 if key == 'lreal': 

1534 if isinstance(val, str): 

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

1536 elif isinstance(val, bool): 

1537 if val: 

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

1539 else: 

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

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

1542 if val is not None: 

1543 if key == 'ldau_luj': 

1544 # User didn't turn on LDAU tag. 

1545 # Only turn on if ldau is unspecified 

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

1547 self.bool_params['ldau'] = True 

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

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

1550 llist = ulist = jlist = '' 

1551 for symbol in self.symbol_count: 

1552 # default: No +U 

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

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

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

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

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

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

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

1560 

1561 if (self.spinpol and not magmom_written 

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

1563 # but we could still be doing a spinpol calculation 

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

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

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

1567 # Write out initial magnetic moments 

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

1569 # unpack magmom array if three components specified 

1570 if magmom.ndim > 1: 

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

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

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

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

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

1576 else: 

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

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

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

1580 incar.write('\n') 

1581 

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

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

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

1585 # reliably and easily identify such non-standard entries 

1586 custom_kv_pairs = p.get('custom') 

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

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

1589 key.upper(), value)) 

1590 incar.close() 

1591 

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

1593 """Writes the KPOINTS file.""" 

1594 

1595 if atoms is None: 

1596 atoms = self.atoms 

1597 

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

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

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

1601 return 

1602 else: 

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

1604 "Please use None or a positive number." 

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

1606 

1607 p = self.input_params 

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

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

1610 

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

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

1613 p['reciprocal'] = True 

1614 

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

1616 

1617 # Wrap scalar in list if necessary 

1618 if shape == (): 

1619 p['kpts'] = [p['kpts']] 

1620 shape = (1, ) 

1621 

1622 if len(shape) == 1: 

1623 kpoints.write('0\n') 

1624 if shape == (1, ): 

1625 kpoints.write('Auto\n') 

1626 elif p['gamma']: 

1627 kpoints.write('Gamma\n') 

1628 else: 

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

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

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

1632 elif len(shape) == 2: 

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

1634 if p['reciprocal']: 

1635 kpoints.write('Reciprocal\n') 

1636 else: 

1637 kpoints.write('Cartesian\n') 

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

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

1640 if shape[1] == 4: 

1641 kpoints.write('\n') 

1642 elif shape[1] == 3: 

1643 kpoints.write('1.0 \n') 

1644 

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

1646 """Writes the POTCAR file.""" 

1647 

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

1649 for filename in self.ppp_list: 

1650 with open_potcar(filename=filename) as ppp_file: 

1651 for line in ppp_file: 

1652 potfile.write(line) 

1653 

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

1655 """Writes a sortings file. 

1656 

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

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

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

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

1661 

1662 with open(join(directory, 'ase-sort.dat'), 'w') as fd: 

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

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

1665 

1666 # The below functions are used to restart a calculation 

1667 

1668 def read_incar(self, filename): 

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

1670 

1671 Typically named INCAR.""" 

1672 

1673 self.spinpol = False 

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

1675 lines = fd.readlines() 

1676 

1677 for line in lines: 

1678 try: 

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

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

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

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

1683 data = line.split() 

1684 # Skip empty and commented lines. 

1685 if len(data) == 0: 

1686 continue 

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

1688 continue 

1689 key = data[0].lower() 

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

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

1692 # Unconditionally add it, no type checking 

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

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

1695 # value should be '1 2 3' 

1696 

1697 # Split at first occurence of "=" 

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

1699 # First "#" denotes beginning of comment 

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

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

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

1703 elif key in float_keys: 

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

1705 elif key in exp_keys: 

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

1707 elif key in string_keys: 

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

1709 elif key in int_keys: 

1710 if key == 'ispin': 

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

1712 # out 

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

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

1715 self.spinpol = True 

1716 else: 

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

1718 elif key in bool_keys: 

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

1720 self.bool_params[key] = True 

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

1722 self.bool_params[key] = False 

1723 

1724 elif key in list_bool_keys: 

1725 self.list_bool_params[key] = [ 

1726 _from_vasp_bool(x) 

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

1728 ] 

1729 

1730 elif key in list_int_keys: 

1731 self.list_int_params[key] = [ 

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

1733 ] 

1734 

1735 elif key in list_float_keys: 

1736 if key == 'magmom': 

1737 lst = [] 

1738 i = 2 

1739 while i < len(data): 

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

1741 break 

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

1743 b = lst.pop() 

1744 i += 1 

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

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

1747 else: 

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

1749 i += 1 

1750 self.list_float_params['magmom'] = lst 

1751 lst = np.array(lst) 

1752 if self.atoms is not None: 

1753 self.atoms.set_initial_magnetic_moments( 

1754 lst[self.resort]) 

1755 else: 

1756 data = _args_without_comment(data) 

1757 self.list_float_params[key] = [ 

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

1759 ] 

1760 # elif key in list_keys: 

1761 # list = [] 

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

1763 # 'ropt', 'rwigs', 

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

1765 # for a in data[2:]: 

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

1767 # break 

1768 # list.append(float(a)) 

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

1770 # for a in data[2:]: 

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

1772 # break 

1773 # list.append(int(a)) 

1774 # self.list_params[key] = list 

1775 # if key == 'magmom': 

1776 # list = [] 

1777 # i = 2 

1778 # while i < len(data): 

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

1780 # break 

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

1782 # b = list.pop() 

1783 # i += 1 

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

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

1786 # else: 

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

1788 # i += 1 

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

1790 # list = np.array(list) 

1791 # if self.atoms is not None: 

1792 # self.atoms.set_initial_magnetic_moments( 

1793 # list[self.resort]) 

1794 elif key in special_keys: 

1795 if key == 'lreal': 

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

1797 self.special_params[key] = True 

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

1799 self.special_params[key] = False 

1800 else: 

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

1802 except KeyError: 

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

1804 'not known by calculator.' % key) 

1805 except IndexError: 

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

1807 

1808 def read_kpoints(self, filename): 

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

1810 # If we used VASP builtin kspacing, 

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

1812 # Don't update kpts array 

1813 return 

1814 

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

1816 lines = fd.readlines() 

1817 

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

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

1820 if ktype == 'g': 

1821 self.set(gamma=True) 

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

1823 elif ktype == 'a': 

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

1825 elif ktype == 'm': 

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

1827 else: 

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

1829 self.set(reciprocal=False) 

1830 else: 

1831 self.set(reciprocal=True) 

1832 kpts = np.array( 

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

1834 self.set(kpts=kpts) 

1835 

1836 def read_potcar(self, filename): 

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

1838 """ 

1839 

1840 # Search for key 'LEXCH' in POTCAR 

1841 xc_flag = None 

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

1843 for line in fd: 

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

1845 if key == 'LEXCH': 

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

1847 break 

1848 

1849 if xc_flag is None: 

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

1851 

1852 # Values of parameter LEXCH and corresponding XC-functional 

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

1854 

1855 if xc_flag not in xc_dict.keys(): 

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

1857 ' LEXCH=%s' % xc_flag) 

1858 

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

1860 

1861 def todict(self): 

1862 """Returns a dictionary of all parameters 

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

1864 dict_list = [ 

1865 'float_params', 'exp_params', 'string_params', 'int_params', 

1866 'bool_params', 'list_bool_params', 'list_int_params', 

1867 'list_float_params', 'special_params', 'dict_params', 

1868 'input_params' 

1869 ] 

1870 dct = {} 

1871 for item in dict_list: 

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

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

1874 return dct 

1875 

1876 

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

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

1879 

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

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

1882 

1883 """ 

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

1885 if comment_locs == []: 

1886 return data 

1887 else: 

1888 return data[:min(comment_locs)] 

1889 

1890 

1891def _from_vasp_bool(x): 

1892 """Cast vasp boolean to Python bool 

1893 

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

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

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

1897 

1898 """ 

1899 assert isinstance(x, str) 

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

1901 return True 

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

1903 return False 

1904 else: 

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

1906 

1907 

1908def _to_vasp_bool(x): 

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

1910 

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

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

1913 

1914 """ 

1915 if isinstance(x, str): 

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

1917 x = True 

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

1919 x = False 

1920 else: 

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

1922 assert isinstance(x, bool) 

1923 if x: 

1924 return '.TRUE.' 

1925 else: 

1926 return '.FALSE.' 

1927 

1928 

1929def open_potcar(filename): 

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

1931 """ 

1932 import gzip 

1933 if filename.endswith('R'): 

1934 return open(filename, 'r') 

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

1936 return gzip.open(filename) 

1937 else: 

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

1939 

1940 

1941def read_potcar_numbers_of_electrons(file_obj): 

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

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

1944 nelect = [] 

1945 lines = file_obj.readlines() 

1946 for n, line in enumerate(lines): 

1947 if 'TITEL' in line: 

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

1949 valence = float( 

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

1951 nelect.append((symbol, valence)) 

1952 return nelect 

1953 

1954 

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

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

1957 

1958 Parameters: 

1959 atoms: Atoms object to be grouped 

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

1961 

1962 Returns: 

1963 Tuple of (symbols, symbolcount) 

1964 symbols: The unique symbols in the included list 

1965 symbolscount: Count of symbols in the included list 

1966 

1967 Example: 

1968 

1969 >>> from ase.build import bulk 

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

1971 >>> count_symbols(atoms) 

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

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

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

1975 """ 

1976 symbols = [] 

1977 symbolcount = {} 

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

1979 if m in exclude: 

1980 continue 

1981 if symbol not in symbols: 

1982 symbols.append(symbol) 

1983 symbolcount[symbol] = 1 

1984 else: 

1985 symbolcount[symbol] += 1 

1986 return symbols, symbolcount