Coverage for /builds/debichem-team/python-ase/ase/calculators/vasp/create_input.py: 68.18%

616 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2025-03-06 04:00 +0000

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 shutil 

23import warnings 

24from os.path import isfile, islink, join 

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 

32from ase.config import cfg 

33from ase.io.vasp_parsers.incar_writer import write_incar 

34 

35FLOAT_FORMAT = '5.6f' 

36EXP_FORMAT = '5.2e' 

37 

38 

39def check_ichain(ichain, ediffg, iopt): 

40 ichain_dct = {} 

41 if ichain > 0: 

42 ichain_dct['ibrion'] = 3 

43 ichain_dct['potim'] = 0.0 

44 if iopt is None: 

45 warnings.warn( 

46 'WARNING: optimization is set to LFBGS (IOPT = 1)') 

47 ichain_dct['iopt'] = 1 

48 if ediffg is None or float(ediffg > 0.0): 

49 raise RuntimeError('Please set EDIFFG < 0') 

50 return ichain_dct 

51 

52 

53def set_magmom(ispin, spinpol, atoms, magmom_input, sorting): 

54 """Helps to set the magmom tag in the INCAR file with correct formatting""" 

55 magmom_dct = {} 

56 if magmom_input is not None: 

57 if len(magmom_input) != len(atoms): 

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

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

60 len(atoms), len(magmom_input)) 

61 raise ValueError(msg) 

62 

63 # Check if user remembered to specify ispin 

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

65 if not ispin: 

66 spinpol = True 

67 # note that ispin is an int key, but for the INCAR it does not 

68 # matter 

69 magmom_dct['ispin'] = 2 

70 magmom = np.array(magmom_input) 

71 magmom = magmom[sorting] 

72 elif (spinpol and atoms.get_initial_magnetic_moments().any()): 

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

74 # but we could still be doing a spinpol calculation 

75 if not ispin: 

76 magmom_dct['ispin'] = 2 

77 # Write out initial magnetic moments 

78 magmom = atoms.get_initial_magnetic_moments()[sorting] 

79 # unpack magmom array if three components specified 

80 if magmom.ndim > 1: 

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

82 else: 

83 return spinpol, {} 

84 # Compactify the magmom list to symbol order 

85 lst = [[1, magmom[0]]] 

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

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

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

89 else: 

90 lst.append([1, magmom[n]]) 

91 line = ' '.join(['{:d}*{:.4f}'.format(mom[0], mom[1]) 

92 for mom in lst]) 

93 magmom_dct['magmom'] = line 

94 return spinpol, magmom_dct 

95 

96 

97def set_ldau(ldau_param, luj_params, symbol_count): 

98 """Helps to set the ldau tag in the INCAR file with correct formatting""" 

99 ldau_dct = {} 

100 if ldau_param is None: 

101 ldau_dct['ldau'] = '.TRUE.' 

102 llist = [] 

103 ulist = [] 

104 jlist = [] 

105 for symbol in symbol_count: 

106 # default: No +U 

107 luj = luj_params.get( 

108 symbol[0], 

109 {'L': -1, 'U': 0.0, 'J': 0.0} 

110 ) 

111 llist.append(int(luj['L'])) 

112 ulist.append(f'{luj["U"]:{".3f"}}') 

113 jlist.append(f'{luj["J"]:{".3f"}}') 

114 ldau_dct['ldaul'] = llist 

115 ldau_dct['ldauu'] = ulist 

116 ldau_dct['ldauj'] = jlist 

117 return ldau_dct 

118 

119 

120def test_nelect_charge_compitability(nelect, charge, nelect_from_ppp): 

121 # We need to determine the nelect resulting from a given 

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

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

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

125 if charge is not None and charge != 0: 

126 nelect_from_charge = nelect_from_ppp - charge 

127 if nelect and nelect != nelect_from_charge: 

128 raise ValueError('incompatible input parameters: ' 

129 f'nelect={nelect}, but charge={charge} ' 

130 '(neutral nelect is ' 

131 f'{nelect_from_ppp})') 

132 print(nelect_from_charge) 

133 return nelect_from_charge 

134 else: 

135 return nelect 

136 

137 

138def get_pp_setup(setup) -> Tuple[dict, Sequence[int]]: 

139 """ 

140 Get the pseudopotential mapping based on the "setpus" input. 

141 

142 Parameters 

143 ---------- 

144 setup : [str, dict] 

145 The setup to use for the calculation. This can be a string 

146 shortcut, or a dict of atom identities and suffixes. 

147 In the dict version it is also possible to select a base setup 

148 e.g.: {'base': 'minimal', 'Ca': '_sv', 2: 'O_s'} 

149 If the key is an integer, this means an atom index. 

150 For the string version, 'minimal', 'recommended' and 'GW' are 

151 available. The default is 'minimal 

152 

153 Returns 

154 ------- 

155 setups : dict 

156 The setup dictionary, with atom indices as keys and suffixes 

157 as values. 

158 special_setups : list 

159 A list of atom indices that have a special setup. 

160 """ 

161 special_setups = [] 

162 

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

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

165 setups_defaults = get_default_setups() 

166 

167 # Default to minimal basis 

168 if setup is None: 

169 setup = {'base': 'minimal'} 

170 

171 # String shortcuts are initialised to dict form 

172 elif isinstance(setup, str): 

173 if setup.lower() in setups_defaults.keys(): 

174 setup = {'base': setup} 

175 

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

177 if 'base' in setup: 

178 setups = setups_defaults[setup['base'].lower()] 

179 else: 

180 setups = {} 

181 

182 # Override defaults with user-defined setups 

183 if setup is not None: 

184 setups.update(setup) 

185 

186 for m in setups: 

187 try: 

188 special_setups.append(int(m)) 

189 except ValueError: 

190 pass 

191 return setups, special_setups 

192 

193 

194def format_kpoints(kpts, atoms, reciprocal=False, gamma=False): 

195 tokens = [] 

196 append = tokens.append 

197 

198 append('KPOINTS created by Atomic Simulation Environment\n') 

199 

200 if isinstance(kpts, dict): 

201 kpts = kpts2ndarray(kpts, atoms=atoms) 

202 reciprocal = True 

203 

204 shape = np.array(kpts).shape 

205 

206 # Wrap scalar in list if necessary 

207 if shape == (): 

208 kpts = [kpts] 

209 shape = (1, ) 

210 

211 if len(shape) == 1: 

212 append('0\n') 

213 if shape == (1, ): 

214 append('Auto\n') 

215 elif gamma: 

216 append('Gamma\n') 

217 else: 

218 append('Monkhorst-Pack\n') 

219 append(' '.join(f'{kpt:d}' for kpt in kpts)) 

220 append('\n0 0 0\n') 

221 elif len(shape) == 2: 

222 append('%i \n' % (len(kpts))) 

223 if reciprocal: 

224 append('Reciprocal\n') 

225 else: 

226 append('Cartesian\n') 

227 for n in range(len(kpts)): 

228 [append('%f ' % kpt) for kpt in kpts[n]] 

229 if shape[1] == 4: 

230 append('\n') 

231 elif shape[1] == 3: 

232 append('1.0 \n') 

233 return ''.join(tokens) 

234 

235 

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

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

238 

239float_keys = [ 

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

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

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

243 'aldac', # Fraction of LDA correlation energy 

244 'amin', # 

245 'amix', # 

246 'amix_mag', # 

247 'bmix', # tags for mixing 

248 'bmix_mag', # 

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

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

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

252 # (EDIFF/N-BANDS/4) 

253 'efield', # applied electrostatic field 

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

255 'emin', # 

256 'enaug', # Density cutoff 

257 'encut', # Planewave cutoff 

258 'encutgw', # energy cutoff for response function 

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

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

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

262 # file is not present. KSPACING is the smallest 

263 # allowed spacing between k-points in units of 

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

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

266 'nelect', # total number of electrons 

267 'param1', # Exchange parameter 

268 'param2', # Exchange parameter 

269 'pomass', # mass of ions in am 

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

271 # pstress 

272 'sigma', # broadening in eV 

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

274 'spring', # spring constant for NEB 

275 'time', # special control tag 

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

277 'zab_vdw', # vdW-DF parameter 

278 'zval', # ionic valence 

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

280 # group at UT Austin 

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

282 'ddr', # (DdR) dimer separation 

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

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

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

286 'sltol', # convergence ratio for minimum eigenvalue 

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

288 # size when translating 

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

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

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

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

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

294 'ftimemax', # Max time step 

295 'ftimedec', # Factor to dec. dt 

296 'ftimeinc', # Factor to inc. dt 

297 'falpha', # Parameter for velocity damping 

298 'falphadec', # Factor to dec. alpha 

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

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

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

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

303 # correction 

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

305 # and Scheffler's DFT-TS dispersion corrections 

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

307 # Grimme's DFT-D3 dispersion correction 

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

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

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

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

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

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

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

315 'eb_k', # solvent permitivity in Vaspsol 

316 'tau', # surface tension parameter in Vaspsol 

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

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

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

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

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

322 'tebeg', # 

323 'teend', # temperature during run 

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

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

326 'auger_ecblo', # Undocumented parameter for Auger calculations 

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

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

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

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

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

332 'auger_occ_fac_eeh', # Undocumented parameter for Auger calculations 

333 'auger_occ_fac_ehh', # Undocumented parameter for Auger calculations 

334 'auger_temp', # Temperature for Auger calculation 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

356 'soltemp', # Solvent temperature for isol 2 in Vaspsol++ 

357 'a_k', # Smoothing length for FFT for isol 2 in Vaspsol++ 

358 'r_cav', # Offset for solute surface area for isol 2 in Vaspsol++ 

359 'epsilon_inf', # Bulk optical dielectric for isol 2 in Vaspsol++ 

360 'n_mol', # Solvent density for isol 2 in Vaspsol++ 

361 'p_mol', # Solvent dipole moment for isol 2 in Vaspsol++ 

362 'r_solv', # Solvent radius for isol 2 in Vaspsol++ 

363 'r_diel', # Dielectric radius for isol 2 in Vaspsol++ 

364 'r_b', # Bound charge smearing length for isol 2 in Vaspsol++ 

365 'c_molar', # Electrolyte concentration for isol 2 in Vaspsol++ 

366 'zion', # Electrolyte ion valency for isol 2 in Vaspsol++ 

367 'd_ion', # Packing diameter of electrolyte ions for isol 2 in Vaspsol++ 

368 'r_ion', # Ionic radius of electrolyte ions for isol 2 in Vaspsol++ 

369 'efermi_ref', # Potential vs vacuum for isol 2 in Vaspsol++ 

370 'capacitance_init', # Initial guess for isol 2 in Vaspsol++ 

371 'deg_threshold', # Degeneracy threshold 

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

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

374 'rtime', # Undocumented parameter 

375 'wplasma', # Undocumented parameter 

376 'wplasmai', # Undocumented parameter 

377 'dfield', # Undocumented parameter 

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

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

380 'encutlf', # Undocumented parameter 

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

382 'dimer_dist', # Distance between dimer images 

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

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

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

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

387 'shaketol', # Tolerance for SHAKE algorithm 

388 'shaketolsoft', # Soft tolerance for SHAKE algorithm 

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

390 'hills_stride', # Undocumented metadynamics parameter 

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

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

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

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

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

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

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

398 'dvvdelta0', # Undocumented parameter 

399 'dvvvnorm0', # Undocumented parameter 

400 'dvvminpotim', # Undocumented parameter 

401 'dvvmaxpotim', # Undocumented parameter 

402 'enchg', # Undocumented charge fitting parameter 

403 'tau0', # Undocumented charge fitting parameter 

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

405 'param3', # Undocumented HF parameter 

406 'model_eps0', # Undocumented HF parameter 

407 'model_alpha', # Undocumented HF parameter 

408 'qmaxfockae', # Undocumented HF parameter 

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

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

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

412 'encutsubrotscf', # Undocumented subspace rotation SCF parameter 

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

414 'wc', # Undocumented mixing parameter 

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

416 'scalee', # Undocumented parameter 

417 'eref', # Reference energy 

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

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

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

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

422 'lj_radius', # Undocumented classical vdW parameter 

423 'lj_epsilon', # Undocumented classical vdW parameter 

424 'lj_sigma', # Undocumented classical vdW parameter 

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

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

427 'hitoler', # Iterative Hirschfeld partitioning tolerance 

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

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

430 'maxpwamp', # Undocumented HF parameter 

431 'vcutoff', # Undocumented parameter 

432 'mdtemp', # Temperature for AIMD 

433 'mdgamma', # Undocumented AIMD parameter 

434 'mdalpha', # Undocumented AIMD parameter 

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

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

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

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

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

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

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

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

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

444 'qtpz', # Temperature (instanton) 

445 'qftol', # Tolerance (instanton) 

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

447] 

448 

449exp_keys = [ 

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

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

452 'symprec', # precession in symmetry routines 

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

454 # group at UT Austin 

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

456] 

457 

458string_keys = [ 

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

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

461 'metagga', # 

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

463 'system', # name of System 

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

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

466 'localized_basis', # Basis to use in CRPA 

467 'proutine', # Select profiling routine 

468 'efermi', # Sets the FERMI level in VASP 6.4.0+ 

469] 

470 

471int_keys = [ 

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

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

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

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

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

477 'imix', # specifies density mixing 

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

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

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

481 'ispin', # spin-polarized calculation 

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

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

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

485 'kpar', # k-point parallelization paramater 

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

487 # written 

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

489 'lmaxmix', # 

490 'lorbit', # create PROOUT 

491 'maxmix', # 

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

493 'ngxf', # FFT mesh for charges x 

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

495 'ngyf', # FFT mesh for charges y 

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

497 'ngzf', # FFT mesh for charges z 

498 'nbands', # Number of bands 

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

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

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

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

503 'nelmgw', # nr. of self-consistency cycles for GW 

504 'nelmin', 

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

506 # finite differences 

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

508 # nkredx=nkredy=nkredz 

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

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

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

512 'nomega', # number of frequency points 

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

514 'npar', # parallelization over bands 

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

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

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

518 'vdwgr', # extra keyword for Andris program 

519 'vdwrn', # extra keyword for Andris program 

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

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

522 # group at UT Austin 

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

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

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

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

527 # and potim = 0.0 

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

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

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

531 'icorelevel', # core level shifts 

532 'clnt', # species index 

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

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

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

536 'nbandsgw', # Number of bands for GW 

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

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

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

540 # by npar 

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

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

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

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

545 # (Possibly Depricated) Number of groups in real time for 

546 # response function calc. 

547 'taupar', 

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

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

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

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

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

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

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

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

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

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

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

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

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

561 'ibse', # Type of BSE calculation 

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

563 'naturalo', # Use NATURALO (?) 

564 'nbandsexact', # Undocumented parameter 

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

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

567 'omegagrid', # Undocumented parameter 

568 'telescope', # Undocumented parameter 

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

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

571 'dim', # Undocumented parameter 

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

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

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

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

576 'lmaxmp2', # Undocumented parameter 

577 'switch', # Undocumented dimer parameter 

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

579 'engine', # Undocumented dimer parameter 

580 'restartcg', # Undocumented dimer parameter 

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

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

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

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

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

586 'hills_maxstride', # Undocumented metadynamics parameter 

587 'dvvehistory', # Undocumented parameter 

588 'ipead', # Undocumented parameter 

589 'ngaus', # Undocumented charge fitting parameter 

590 'exxoep', # Undocumented HF parameter 

591 'fourorbit', # Undocumented HF parameter 

592 'model_gw', # Undocumented HF parameter 

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

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

595 'lmaxfockae', # Undocumented HF parameter 

596 'nmaxfockae', # Undocumented HF parameter 

597 'nblock_fock', # Undocumented HF parameter 

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

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

600 'mremove', # Undocumented mixing parameter 

601 'inimix', # Undocumented mixing parameter 

602 'mixpre', # Undocumented mixing parameter 

603 'nelmall', # Undocumented parameter 

604 'nblock', # How frequently to write data 

605 'kblock', # How frequently to write data 

606 'npaco', # Undocumented pair correlation function parameter 

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

608 'irestart', # Undocumented parameter 

609 'nreboot', # Undocumented parameter 

610 'nmin', # Undocumented parameter 

611 'nlspline', # Undocumented parameter 

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

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

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

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

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

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

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

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

620 'nbands_out', # Undocumented QP parameter 

621 'kpts_out', # Undocumented QP parameter 

622 'isp_out', # Undocumented QP parameter 

623 'nomega_out', # Undocumented QP parameter 

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

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

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

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

628 'ncore_in_image1', # Undocumented parameter 

629 'kimages', # Undocumented parameter 

630 'ncores_per_band', # Undocumented parameter 

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

632 'ncrpalow', # Undocumented CRPA parameter 

633 'ncrpahigh', # Undocumented CRPA parameter 

634 'nwlow', # Undocumented parameter 

635 'nwhigh', # Undocumented parameter 

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

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

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

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

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

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

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

643 'isol', # vaspsol++ flag 1 linear, 2 nonlinear 

644] 

645 

646bool_keys = [ 

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

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

649 # centred at the $\Gamma$ 

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

651 # (KGAMMA=.TRUE.) 

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

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

654 # VASP.5.X) 

655 'lasync', # overlap communcation with calculations 

656 'lcharg', # 

657 'lcorr', # Harris-correction to forces 

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

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

660 'ldipol', # potential correction mode 

661 'lelf', # create ELFCAR 

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

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

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

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

666 # density 

667 'lplane', # parallelisation over the FFT grid 

668 'lscalapack', # switch off scaLAPACK 

669 'lscalu', # switch of LU decomposition 

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

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

672 'lthomas', # 

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

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

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

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

677 'lwave', # 

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

679 # group at UT Austin 

680 'lclimb', # Turn on CI-NEB 

681 'ltangentold', # Old central difference tangent 

682 'ldneb', # Turn on modified double nudging 

683 'lnebcell', # Turn on SS-NEB 

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

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

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

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

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

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

690 # tensors (vasp 5.2) 

691 'lvdw', # Turns on dispersion correction 

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

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

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

695 # polarizability 

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

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

698 'lsorbit', # Enable spin-orbit coupling 

699 'lsol', # turn on solvation for Vaspsol 

700 'lnldiel', # turn on nonlinear dielectric in Vaspsol++ 

701 'lnlion', # turn on nonlinear ionic in Vaspsol++ 

702 'lsol_scf', # turn on solvation in SCF cycle in Vaspsol++ 

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

704 'interactive', # Enables interactive calculation for VaspInteractive 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

735 'lmixtau', # Undocumented MetaGGA parameter 

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

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

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

739 'lnabla', # Undocumented parameter 

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

741 'lvel', # Undocumented parameter 

742 'lrpaforce', # Calculate RPA forces 

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

744 'ladder', # Use ladder diagrams 

745 'lfxc', # Use approximate ladder diagrams 

746 'lrsrpa', # Undocumented parameter 

747 'lsingles', # Calculate HF singles 

748 'lfermigw', # Iterate Fermi level 

749 'ltcte', # Undocumented parameter 

750 'ltete', # Undocumented parameter 

751 'ltriplet', # Undocumented parameter 

752 'lfxceps', # Undocumented parameter 

753 'lfxheg', # Undocumented parameter 

754 'l2order', # Undocumented parameter 

755 'lmp2lt', # Undocumented parameter 

756 'lgwlf', # Undocumented parameter 

757 'lusew', # Undocumented parameter 

758 'selfenergy', # Undocumented parameter 

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

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

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

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

763 'fletcher_reeves', # Undocumented dimer parameter 

764 'lidm_selective', # Undocumented dimer parameter 

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

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

767 'dvvminus', # Undocumented parameter 

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

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

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

771 'lchgfit', # Turn on charge fitting 

772 'lgausrc', # Undocumented charge fitting parameter 

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

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

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

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

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

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

779 'shiftred', # Undocumented HF parameter 

780 'hfkident', # Undocumented HF parameter 

781 'oddonly', # Undocumented HF parameter 

782 'evenonly', # Undocumented HF parameter 

783 'lfockaedft', # Undocumented HF parameter 

784 'lsubrot', # Enable subspace rotation diagonalization 

785 'mixfirst', # Mix before diagonalization 

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

787 'lcompat', # Enable "full compatibility" 

788 'lmusic', # "Joke" parameter 

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

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

791 'lorbitalreal', # Undocumented parameter 

792 'lmetagga', # Undocumented parameter 

793 'lspiral', # Undocumented parameter 

794 'lzeroz', # Undocumented parameter 

795 'lmono', # Enable "monopole" corrections 

796 'lrelcore', # Perform relaxed core calculation 

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

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

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

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

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

802 'lrelvol', # Undocumented classical vdW parameter 

803 'lj_only', # Undocumented classical vdW parameter 

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

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

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

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

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

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

810 'lvdw_relvolone', # Undocumented classical vdW parameter 

811 'lberry', # Enable Berry-phase calculation 

812 'lpade_fit', # Undocumented QP parameter 

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

814 'l_wr_moments', # Undocumented parameter 

815 'l_wr_density', # Undocumented parameter 

816 'lkotani', # Undocumented parameter 

817 'ldyson', # Undocumented parameter 

818 'laddherm', # Undocumented parameter 

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

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

821 'ldisentangle', # Disentangle bands in CRPA 

822 'lweighted', # "Weighted" CRPA approach 

823 'luseorth_lcaos', # Use orthogonalized LCAOs in CRPA 

824 'lfrpa', # Use full RPA in CRPA 

825 'lregularize', # Regularize projectors in CRPA 

826 'ldrude', # Include Drude term in CRPA 

827 'ldmatrix', # Undocumented parameter 

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

829 'lhyperfine', # Enable Hyperfine calculation 

830 'lwannier', # Enable Wannier interface 

831 'localize', # Undocumented Wannier parameter 

832 'lintpol_wpot', # Interpolate WPOT for Wannier 

833 'lintpol_orb', # Interpolate orbitals for Wannier 

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

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

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

837 'lintpol_velocity', # Interpolate electron velocity for Wannier 

838 'lintpol_conductivity', # Interpolate conductivity for Wannier 

839 'lwannierinterpol', # Undocumented Wannier parameter 

840 'wanproj', # Undocumented Wannier parameter 

841 'lorbmom', # Undocumented LDA+U parameter 

842 'lwannier90_run', # Undocumented WANNIER90 parameter 

843 'lwrite_wanproj', # Write UWAN files for WANNIER90 

844 'lwrite_unk', # Write UNK files for WANNIER90 

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

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

847 'lrhfatm', # Undocumented HF parameter 

848 'lvpot', # Calculate unscreened potential 

849 'lwpot', # Calculate screened potential 

850 'lwswq', # Undocumented parameter 

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

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

853 'qdo_ins', # Find instanton 

854 'qdo_pre', # Calculate prefactor (instanton) 

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

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

857 'lnbo', # Enable NBO analysis 

858] 

859 

860list_int_keys = [ 

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

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

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

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

865 # (Bucko) 

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

867 'auger_bmax_eeh', # 4 ints | calculations 

868 'auger_bmin_ehh', # 4 ints | 

869 'auger_bmax_ehh', # 4 ints | 

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

871 'kpoint_bse', # 4 ints | Undocumented parameter 

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

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

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

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

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

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

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

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

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

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

882] 

883 

884list_bool_keys = [ 

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

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

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

888] 

889 

890list_float_keys = [ 

891 'dipol', # center of cell for dipol 

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

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

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

895 'magmom', # initial magnetic moments 

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

897 'rwigs', # Wigner-Seitz radii 

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

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

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

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

902 # when a calculation is set up 

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

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

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

906 # (DFT-TS) 

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

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

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

910 # (DFT-TS) 

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

912 # species (DFT-TS) 

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

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

915 'auger_emax_eeh', # 4 floats | calculations 

916 'auger_emin_ehh', # 4 floats | 

917 'auger_emax_ehh', # 4 floats | 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

950 'qspiral', # 3 floats | Undocumented parameter 

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

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

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

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

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

956 'ofield_k', # 3 floats | Undocumented parameter 

957 'paripot', # ? floats | Undocumented parameter 

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

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

960] 

961 

962special_keys = [ 

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

964] 

965 

966dict_keys = [ 

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

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

969] 

970 

971keys: List[str] = [ 

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

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

974 # 'WEIMIN, EBREAK, DEPER special control tags 

975] 

976 

977 

978class GenerateVaspInput: 

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

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

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

982 xc_defaults = { 

983 'lda': { 

984 'pp': 'LDA' 

985 }, 

986 # GGAs 

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

988 'pp': 'PBE', 

989 'gga': 'B5', 

990 'aldax': 1.00, 

991 'aggax': 1.00, 

992 'aggac': 1.00, 

993 'aldac': 0.00 

994 }, 

995 'pw91': { 

996 'pp': 'PW91', 

997 'gga': '91' 

998 }, 

999 'pbe': { 

1000 'pp': 'PBE', 

1001 'gga': 'PE' 

1002 }, 

1003 'pbesol': { 

1004 'gga': 'PS' 

1005 }, 

1006 'revpbe': { 

1007 'gga': 'RE' 

1008 }, 

1009 'rpbe': { 

1010 'gga': 'RP' 

1011 }, 

1012 'am05': { 

1013 'gga': 'AM' 

1014 }, 

1015 # Meta-GGAs 

1016 'tpss': { 

1017 'metagga': 'TPSS' 

1018 }, 

1019 'revtpss': { 

1020 'metagga': 'RTPSS' 

1021 }, 

1022 'm06l': { 

1023 'metagga': 'M06L' 

1024 }, 

1025 'ms0': { 

1026 'metagga': 'MS0' 

1027 }, 

1028 'ms1': { 

1029 'metagga': 'MS1' 

1030 }, 

1031 'ms2': { 

1032 'metagga': 'MS2' 

1033 }, 

1034 'scan': { 

1035 'metagga': 'SCAN' 

1036 }, 

1037 'rscan': { 

1038 'metagga': 'RSCAN' 

1039 }, 

1040 'r2scan': { 

1041 'metagga': 'R2SCAN' 

1042 }, 

1043 'scan-rvv10': { 

1044 'metagga': 'SCAN', 

1045 'luse_vdw': True, 

1046 'bparam': 15.7 

1047 }, 

1048 'mbj': { 

1049 # Modified Becke-Johnson 

1050 'metagga': 'MBJ', 

1051 }, 

1052 'tb09': { 

1053 # Alias for MBJ 

1054 'metagga': 'MBJ', 

1055 }, 

1056 # vdW-DFs 

1057 'vdw-df': { 

1058 'gga': 'RE', 

1059 'luse_vdw': True, 

1060 'aggac': 0. 

1061 }, 

1062 'vdw-df-cx': { 

1063 'gga': 'CX', 

1064 'luse_vdw': True, 

1065 'aggac': 0. 

1066 }, 

1067 'vdw-df-cx0p': { 

1068 'gga': 'CX', 

1069 'luse_vdw': True, 

1070 'aggac': 0., 

1071 'lhfcalc': True, 

1072 'aexx': 0.2, 

1073 'aggax': 0.8 

1074 }, 

1075 'optpbe-vdw': { 

1076 'gga': 'OR', 

1077 'luse_vdw': True, 

1078 'aggac': 0.0 

1079 }, 

1080 'optb88-vdw': { 

1081 'gga': 'BO', 

1082 'luse_vdw': True, 

1083 'aggac': 0.0, 

1084 'param1': 1.1 / 6.0, 

1085 'param2': 0.22 

1086 }, 

1087 'optb86b-vdw': { 

1088 'gga': 'MK', 

1089 'luse_vdw': True, 

1090 'aggac': 0.0, 

1091 'param1': 0.1234, 

1092 'param2': 1.0 

1093 }, 

1094 'vdw-df2': { 

1095 'gga': 'ML', 

1096 'luse_vdw': True, 

1097 'aggac': 0.0, 

1098 'zab_vdw': -1.8867 

1099 }, 

1100 'rev-vdw-df2': { 

1101 'gga': 'MK', 

1102 'luse_vdw': True, 

1103 'param1': 0.1234, 

1104 'param2': 0.711357, 

1105 'zab_vdw': -1.8867, 

1106 'aggac': 0.0 

1107 }, 

1108 'beef-vdw': { 

1109 'gga': 'BF', 

1110 'luse_vdw': True, 

1111 'zab_vdw': -1.8867 

1112 }, 

1113 # Hartree-Fock and hybrids 

1114 'hf': { 

1115 'lhfcalc': True, 

1116 'aexx': 1.0, 

1117 'aldac': 0.0, 

1118 'aggac': 0.0 

1119 }, 

1120 'b3lyp': { 

1121 'gga': 'B3', 

1122 'lhfcalc': True, 

1123 'aexx': 0.2, 

1124 'aggax': 0.72, 

1125 'aggac': 0.81, 

1126 'aldac': 0.19 

1127 }, 

1128 'pbe0': { 

1129 'gga': 'PE', 

1130 'lhfcalc': True 

1131 }, 

1132 'hse03': { 

1133 'gga': 'PE', 

1134 'lhfcalc': True, 

1135 'hfscreen': 0.3 

1136 }, 

1137 'hse06': { 

1138 'gga': 'PE', 

1139 'lhfcalc': True, 

1140 'hfscreen': 0.2 

1141 }, 

1142 'hsesol': { 

1143 'gga': 'PS', 

1144 'lhfcalc': True, 

1145 'hfscreen': 0.2 

1146 }, 

1147 # MN-VFM functionals 

1148 'sogga': { 

1149 'gga': 'SA' 

1150 }, 

1151 'sogga11': { 

1152 'gga': 'S1' 

1153 }, 

1154 'sogga11-x': { 

1155 'gga': 'SX', 

1156 'lhfcalc': True, 

1157 'aexx': 0.401 

1158 }, 

1159 'n12': { 

1160 'gga': 'N2' 

1161 }, 

1162 'n12-sx': { 

1163 'gga': 'NX', 

1164 'lhfcalc': True, 

1165 'lhfscreen': 0.2 

1166 }, 

1167 'mn12l': { 

1168 'metagga': 'MN12L' 

1169 }, 

1170 'gam': { 

1171 'gga': 'GA' 

1172 }, 

1173 'mn15l': { 

1174 'metagga': 'MN15L' 

1175 }, 

1176 'hle17': { 

1177 'metagga': 'HLE17' 

1178 }, 

1179 'revm06l': { 

1180 'metagga': 'revM06L' 

1181 }, 

1182 'm06sx': { 

1183 'metagga': 'M06SX', 

1184 'lhfcalc': True, 

1185 'hfscreen': 0.189, 

1186 'aexx': 0.335 

1187 } 

1188 } 

1189 

1190 # environment variable for PP paths 

1191 VASP_PP_PATH = 'VASP_PP_PATH' 

1192 

1193 def __init__(self, restart=None): 

1194 self.float_params = {} 

1195 self.exp_params = {} 

1196 self.string_params = {} 

1197 self.int_params = {} 

1198 self.bool_params = {} 

1199 self.list_bool_params = {} 

1200 self.list_int_params = {} 

1201 self.list_float_params = {} 

1202 self.special_params = {} 

1203 self.dict_params = {} 

1204 self.atoms = None 

1205 for key in float_keys: 

1206 self.float_params[key] = None 

1207 for key in exp_keys: 

1208 self.exp_params[key] = None 

1209 for key in string_keys: 

1210 self.string_params[key] = None 

1211 for key in int_keys: 

1212 self.int_params[key] = None 

1213 for key in bool_keys: 

1214 self.bool_params[key] = None 

1215 for key in list_bool_keys: 

1216 self.list_bool_params[key] = None 

1217 for key in list_int_keys: 

1218 self.list_int_params[key] = None 

1219 for key in list_float_keys: 

1220 self.list_float_params[key] = None 

1221 for key in special_keys: 

1222 self.special_params[key] = None 

1223 for key in dict_keys: 

1224 self.dict_params[key] = None 

1225 

1226 # Initialize internal dictionary of input parameters which are 

1227 # not regular VASP keys 

1228 self.input_params = { 

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

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

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

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

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

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

1235 'gamma': False, 

1236 # number of points between points in band structures: 

1237 'kpts_nintersections': None, 

1238 # Option to write explicit k-points in units 

1239 # of reciprocal lattice vectors: 

1240 'reciprocal': False, 

1241 # Switch to disable writing constraints to POSCAR 

1242 'ignore_constraints': False, 

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

1244 'charge': None, 

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

1246 # with the sign flipped 

1247 'net_charge': None, 

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

1249 'custom': {}, 

1250 } 

1251 # warning message for pw91 

1252 self.pw91_warning_msg =\ 

1253 "The PW91 (potpaw_GGA) pseudopotential set is " \ 

1254 "from 2006 and not recommended for use.\nWe will " \ 

1255 "remove support for it in a future release, " \ 

1256 "and use the current PBE (potpaw_PBE) set instead.\n" \ 

1257 "Note that this still allows for PW91 calculations, " \ 

1258 "since VASP recalculates the exchange-correlation\n" \ 

1259 "energy inside the PAW sphere and corrects the atomic " \ 

1260 "energies given by the POTCAR file." 

1261 

1262 def set_xc_params(self, xc): 

1263 """Set parameters corresponding to XC functional""" 

1264 xc = xc.lower() 

1265 if xc is None: 

1266 pass 

1267 elif xc not in self.xc_defaults: 

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

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

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

1271 else: 

1272 # print future warning in case pw91 is selected: 

1273 if xc == 'pw91': 

1274 warnings.warn( 

1275 self.pw91_warning_msg, FutureWarning 

1276 ) 

1277 # XC defaults to PBE pseudopotentials 

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

1279 self.set(pp='PBE') 

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

1281 

1282 def set(self, **kwargs): 

1283 

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

1285 and ('ldau_luj' in kwargs)): 

1286 raise NotImplementedError( 

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

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

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

1290 'chemical species in the atoms object. ' 

1291 'For example for a water molecule:' 

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

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

1294 

1295 if 'xc' in kwargs: 

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

1297 for key, value in kwargs.items(): 

1298 if key in self.float_params: 

1299 self.float_params[key] = value 

1300 elif key in self.exp_params: 

1301 self.exp_params[key] = value 

1302 elif key in self.string_params: 

1303 self.string_params[key] = value 

1304 elif key in self.int_params: 

1305 self.int_params[key] = value 

1306 elif key in self.bool_params: 

1307 self.bool_params[key] = value 

1308 elif key in self.list_bool_params: 

1309 self.list_bool_params[key] = value 

1310 elif key in self.list_int_params: 

1311 self.list_int_params[key] = value 

1312 elif key in self.list_float_params: 

1313 self.list_float_params[key] = value 

1314 elif key in self.special_params: 

1315 self.special_params[key] = value 

1316 elif key in self.dict_params: 

1317 self.dict_params[key] = value 

1318 elif key in self.input_params: 

1319 self.input_params[key] = value 

1320 elif isinstance(value, str): 

1321 self.string_params[key] = value 

1322 # `bool` is a subclass of `int` and should be checked earlier. 

1323 # https://docs.python.org/3/c-api/bool.html 

1324 elif isinstance(value, bool): 

1325 self.bool_params[key] = value 

1326 elif isinstance(value, int): 

1327 self.int_params[key] = value 

1328 elif isinstance(value, float): 

1329 self.float_params[key] = value 

1330 elif isinstance(value, list): 

1331 if len(value) == 0: 

1332 msg = f'empty list is given for {key}' 

1333 raise ValueError(msg) 

1334 if isinstance(value[0], bool): 

1335 self.list_bool_params[key] = value 

1336 elif isinstance(value[0], int): 

1337 self.list_int_params[key] = value 

1338 elif isinstance(value[0], float): 

1339 self.list_float_params[key] = value 

1340 else: 

1341 msg = f'cannot handle type of value for {key} = {value!r}' 

1342 raise TypeError(msg) 

1343 else: 

1344 msg = f'cannot handle type of value for {key} = {value!r}' 

1345 raise TypeError(msg) 

1346 

1347 def check_xc(self): 

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

1349 

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

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

1352 """ 

1353 

1354 p = self.input_params 

1355 

1356 # There is no way to correctly guess the desired 

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

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

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

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

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

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

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

1364 warnings.warn( 

1365 self.pw91_warning_msg, FutureWarning 

1366 ) 

1367 

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

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

1370 else: 

1371 raise NotImplementedError( 

1372 "Unable to guess the desired set of pseudopotential" 

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

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

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

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

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

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

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

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

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

1382 "accepted.\n") 

1383 

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

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

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

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

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

1389 "really what you intended!" 

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

1391 

1392 def _make_sort( 

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

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

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

1396 

1397 # Create sorting list 

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

1399 srt.extend(special_setups) 

1400 

1401 for symbol in symbols: 

1402 for m, atom in enumerate(atoms): 

1403 if m in special_setups: 

1404 continue 

1405 if atom.symbol == symbol: 

1406 srt.append(m) 

1407 # Create the resorting list 

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

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

1410 resrt[srt[n]] = n 

1411 return srt, resrt 

1412 

1413 def _set_spinpol(self, atoms): 

1414 if self.int_params['ispin'] is None: 

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

1416 else: 

1417 # VASP runs non-spin-polarized calculations when `ispin=1`, 

1418 # regardless if `magmom` is specified or not. 

1419 self.spinpol = (self.int_params['ispin'] == 2) 

1420 

1421 def _build_pp_list(self, 

1422 atoms, 

1423 setups=None, 

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

1425 """Build the pseudopotential lists""" 

1426 

1427 p = self.input_params 

1428 

1429 if setups is None: 

1430 setups, special_setups = get_pp_setup(p['setups']) 

1431 

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

1433 

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

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

1436 ('pbe', 'potpaw_PBE')): 

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

1438 break 

1439 else: 

1440 pp_folder = p['pp'] 

1441 

1442 if self.VASP_PP_PATH in cfg: 

1443 pppaths = cfg[self.VASP_PP_PATH].split(':') 

1444 else: 

1445 pppaths = [] 

1446 ppp_list = [] 

1447 # Setting the pseudopotentials, first special setups and 

1448 # then according to symbols 

1449 for m in special_setups: 

1450 if m in setups: 

1451 special_setup_index = m 

1452 elif str(m) in setups: 

1453 special_setup_index = str(m) # type: ignore[assignment] 

1454 else: 

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

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

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

1458 for path in pppaths: 

1459 filename = join(path, potcar) 

1460 

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

1462 ppp_list.append(filename) 

1463 break 

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

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

1466 break 

1467 else: 

1468 symbol = atoms.symbols[m] 

1469 msg = """Looking for {}. 

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

1471 potcar, symbol, setups[special_setup_index]) 

1472 raise RuntimeError(msg) 

1473 

1474 for symbol in symbols: 

1475 try: 

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

1477 except (TypeError, KeyError): 

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

1479 for path in pppaths: 

1480 filename = join(path, potcar) 

1481 

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

1483 ppp_list.append(filename) 

1484 break 

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

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

1487 break 

1488 else: 

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

1490 The pseudopotentials are expected to be in: 

1491 LDA: $VASP_PP_PATH/potpaw/ 

1492 PBE: $VASP_PP_PATH/potpaw_PBE/ 

1493 PW91: $VASP_PP_PATH/potpaw_GGA/ 

1494 

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

1496 raise RuntimeError(msg) 

1497 return ppp_list 

1498 

1499 def initialize(self, atoms): 

1500 """Initialize a VASP calculation 

1501 

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

1503 User should specify the PATH 

1504 to the pseudopotentials in VASP_PP_PATH environment variable 

1505 

1506 The pseudopotentials are expected to be in: 

1507 LDA: $VASP_PP_PATH/potpaw/ 

1508 PBE: $VASP_PP_PATH/potpaw_PBE/ 

1509 PW91: $VASP_PP_PATH/potpaw_GGA/ 

1510 

1511 if your pseudopotentials are somewhere else, or named 

1512 differently you may make symlinks at the paths above that 

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

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

1515 """ 

1516 

1517 self.check_xc() 

1518 self.atoms = atoms 

1519 self.all_symbols = atoms.get_chemical_symbols() 

1520 self.natoms = len(atoms) 

1521 

1522 self._set_spinpol(atoms) 

1523 

1524 setups, special_setups = get_pp_setup(self.input_params['setups']) 

1525 

1526 # Determine the number of atoms of each atomic species 

1527 # sorted after atomic species 

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

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

1530 special_setups=special_setups) 

1531 

1532 self.atoms_sorted = atoms[self.sort] 

1533 

1534 # Check if the necessary POTCAR files exists and 

1535 # create a list of their paths. 

1536 atomtypes = atoms.get_chemical_symbols() 

1537 self.symbol_count = [] 

1538 for m in special_setups: 

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

1540 for m in symbols: 

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

1542 

1543 # create pseudopotential list 

1544 self.ppp_list = self._build_pp_list(atoms, 

1545 setups=setups, 

1546 special_setups=special_setups) 

1547 

1548 self.converged = None 

1549 self.setups_changed = None 

1550 

1551 def default_nelect_from_ppp(self): 

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

1553 

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

1555 """ 

1556 symbol_valences = [] 

1557 for filename in self.ppp_list: 

1558 with open_potcar(filename=filename) as ppp_file: 

1559 r = read_potcar_numbers_of_electrons(ppp_file) 

1560 symbol_valences.extend(r) 

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

1562 default_nelect = 0 

1563 for ((symbol1, count), 

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

1565 assert symbol1 == symbol2 

1566 default_nelect += count * valence 

1567 return default_nelect 

1568 

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

1570 from ase.io.vasp import write_vasp 

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

1572 self.atoms_sorted, 

1573 symbol_count=self.symbol_count, 

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

1575 self.write_incar(atoms, directory=directory) 

1576 self.write_potcar(directory=directory) 

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

1578 self.write_sort_file(directory=directory) 

1579 self.copy_vdw_kernel(directory=directory) 

1580 

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

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

1583 Set ASE_VASP_VDW environment variable to the vdw_kernel.bindat 

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

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

1586 

1587 vdw_env = 'ASE_VASP_VDW' 

1588 kernel = 'vdw_kernel.bindat' 

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

1590 

1591 # No need to copy the file again 

1592 if isfile(dst): 

1593 return 

1594 

1595 if self.bool_params['luse_vdw']: 

1596 src = None 

1597 if vdw_env in cfg: 

1598 src = os.path.join(cfg[vdw_env], kernel) 

1599 

1600 if not src or not isfile(src): 

1601 warnings.warn( 

1602 ('vdW has been enabled, however no' 

1603 ' location for the {} file' 

1604 ' has been specified.' 

1605 ' Set {} environment variable to' 

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

1607 else: 

1608 shutil.copyfile(src, dst) 

1609 

1610 def clean(self): 

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

1612 

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

1614 method is called. 

1615 

1616 """ 

1617 files = [ 

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

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

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

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

1622 ] 

1623 for f in files: 

1624 try: 

1625 os.remove(f) 

1626 except OSError: 

1627 pass 

1628 

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

1630 """Writes the INCAR file.""" 

1631 incar_params = {} 

1632 

1633 # float params 

1634 float_dct = { 

1635 key: f'{val:{FLOAT_FORMAT}}' 

1636 for key, val in self.float_params.items() 

1637 if val is not None 

1638 } 

1639 

1640 if 'charge' in self.input_params and self.input_params[ 

1641 'charge'] is not None: 

1642 nelect_val = test_nelect_charge_compitability( 

1643 self.float_params['nelect'], 

1644 self.input_params['charge'], 

1645 self.default_nelect_from_ppp()) 

1646 if nelect_val: 

1647 float_dct['nelect'] = f'{nelect_val:{FLOAT_FORMAT}}' 

1648 incar_params.update(float_dct) 

1649 

1650 # exp params 

1651 exp_dct = { 

1652 key: f'{val:{EXP_FORMAT}}' 

1653 for key, val in self.exp_params.items() 

1654 if val is not None 

1655 } 

1656 incar_params.update(exp_dct) 

1657 

1658 # string_params 

1659 string_dct = { 

1660 key: val for key, val in self.string_params.items() if val is not 

1661 None 

1662 } 

1663 incar_params.update(string_dct) 

1664 

1665 # int params 

1666 int_dct = { 

1667 key: val for key, val in self.int_params.items() if val is not None 

1668 } 

1669 if 'ichain' in int_dct.keys(): 

1670 ichain_dict = check_ichain( 

1671 ichain=int_dct['ichain'], 

1672 ediffg=self.exp_params.get('ediffg', None), 

1673 iopt=int_dct.get('iopt', None), 

1674 ) 

1675 int_dct.update(ichain_dict) 

1676 incar_params.update(int_dct) 

1677 

1678 # list_bool_params 

1679 bool_dct = { 

1680 key: val 

1681 for key, val in self.list_bool_params.items() 

1682 if val is not None 

1683 } 

1684 for key, val in bool_dct.items(): 

1685 bool_dct[key] = [_to_vasp_bool(x) for x in val] 

1686 incar_params.update(bool_dct) 

1687 

1688 # list_int_params 

1689 int_dct = { 

1690 key: val 

1691 for key, val in self.list_int_params.items() 

1692 if val is not None 

1693 } 

1694 if 'ldaul' in int_dct.keys() and self.dict_params[ 

1695 'ldau_luj'] is not None: 

1696 del int_dct['ldaul'] 

1697 incar_params.update(int_dct) 

1698 

1699 # list_float_params 

1700 float_dct = { 

1701 key: val 

1702 for key, val in self.list_float_params.items() 

1703 if val is not None 

1704 } 

1705 if 'ldauu' in float_dct.keys() and self.dict_params[ 

1706 'ldau_luj'] is not None: 

1707 del float_dct['ldauu'] 

1708 if 'ldauj' in float_dct.keys() and self.dict_params[ 

1709 'ldau_luj'] is not None: 

1710 del float_dct['ldauj'] 

1711 incar_params.update(float_dct) 

1712 

1713 # bool params 

1714 bool_dct = { 

1715 key: _to_vasp_bool(val) 

1716 for key, val in self.bool_params.items() 

1717 if val is not None 

1718 } 

1719 incar_params.update(bool_dct) 

1720 

1721 # special params 

1722 special_dct = { 

1723 key: val for key, val in self.special_params.items() if val is not 

1724 None 

1725 } 

1726 if 'lreal' in special_dct.keys(): 

1727 if isinstance(special_dct['lreal'], bool): 

1728 special_dct['lreal'] = _to_vasp_bool(special_dct['lreal']) 

1729 incar_params.update(special_dct) 

1730 

1731 # dict params 

1732 dict_dct = { 

1733 key: val for key, val in self.dict_params.items() if val is not None 

1734 } 

1735 if 'ldau_luj' in dict_dct.keys(): 

1736 ldau_dict = set_ldau( 

1737 ldau_param=self.bool_params['ldau'], 

1738 luj_params=dict_dct['ldau_luj'], 

1739 symbol_count=self.symbol_count) 

1740 dict_dct.update(ldau_dict) 

1741 del dict_dct['ldau_luj'] 

1742 incar_params.update(dict_dct) 

1743 

1744 # set magmom based on input or initial atoms object 

1745 spinpol, magmom_dct = set_magmom( 

1746 atoms=atoms, 

1747 ispin=self.int_params['ispin'], 

1748 spinpol=self.spinpol, 

1749 magmom_input=float_dct.get('magmom', None), 

1750 sorting=self.sort, 

1751 ) 

1752 self.spinpol = spinpol 

1753 incar_params.update(magmom_dct) 

1754 

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

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

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

1758 # reliably and easily identify such non-standard entries 

1759 

1760 cust_dict = { 

1761 key: str(val) + ' # <Custom ASE key>' 

1762 for key, val in self.input_params['custom'].items() 

1763 if val is not None 

1764 } 

1765 incar_params.update(cust_dict) 

1766 

1767 write_incar(directory=directory, parameters=incar_params) 

1768 

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

1770 """Writes the KPOINTS file.""" 

1771 

1772 if atoms is None: 

1773 atoms = self.atoms 

1774 

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

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

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

1778 return 

1779 else: 

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

1781 "Please use None or a positive number." 

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

1783 

1784 kpointstring = format_kpoints( 

1785 kpts=self.input_params['kpts'], 

1786 atoms=atoms, 

1787 reciprocal=self.input_params['reciprocal'], 

1788 gamma=self.input_params['gamma']) 

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

1790 kpoints.write(kpointstring) 

1791 

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

1793 """Writes the POTCAR file.""" 

1794 

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

1796 for filename in self.ppp_list: 

1797 with open_potcar(filename=filename) as ppp_file: 

1798 for line in ppp_file: 

1799 potfile.write(line) 

1800 

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

1802 """Writes a sortings file. 

1803 

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

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

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

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

1808 

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

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

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

1812 

1813 # The below functions are used to restart a calculation 

1814 

1815 def read_incar(self, filename): 

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

1817 

1818 Typically named INCAR.""" 

1819 

1820 self.spinpol = False 

1821 with open(filename) as fd: 

1822 lines = fd.readlines() 

1823 

1824 for line in lines: 

1825 try: 

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

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

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

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

1830 data = line.split() 

1831 # Skip empty and commented lines. 

1832 if len(data) == 0: 

1833 continue 

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

1835 continue 

1836 key = data[0].lower() 

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

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

1839 # Unconditionally add it, no type checking 

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

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

1842 # value should be '1 2 3' 

1843 

1844 # Split at first occurence of "=" 

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

1846 # First "#" denotes beginning of comment 

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

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

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

1850 elif key in float_keys: 

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

1852 elif key in exp_keys: 

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

1854 elif key in string_keys: 

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

1856 elif key in int_keys: 

1857 if key == 'ispin': 

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

1859 # out 

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

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

1862 self.spinpol = True 

1863 else: 

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

1865 elif key in bool_keys: 

1866 val_char = data[2].lower().replace('.', '', 1) 

1867 if val_char.startswith('t'): 

1868 self.bool_params[key] = True 

1869 elif val_char.startswith('f'): 

1870 self.bool_params[key] = False 

1871 else: 

1872 raise ValueError(f'Invalid value "{data[2]}" for bool ' 

1873 f'key "{key}"') 

1874 

1875 elif key in list_bool_keys: 

1876 self.list_bool_params[key] = [ 

1877 _from_vasp_bool(x) 

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

1879 ] 

1880 

1881 elif key in list_int_keys: 

1882 self.list_int_params[key] = [ 

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

1884 ] 

1885 

1886 elif key in list_float_keys: 

1887 if key == 'magmom': 

1888 lst = [] 

1889 i = 2 

1890 while i < len(data): 

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

1892 break 

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

1894 b = lst.pop() 

1895 i += 1 

1896 for _ in range(int(b)): 

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

1898 else: 

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

1900 i += 1 

1901 self.list_float_params['magmom'] = lst 

1902 lst = np.array(lst) 

1903 if self.atoms is not None: 

1904 self.atoms.set_initial_magnetic_moments( 

1905 lst[self.resort]) 

1906 else: 

1907 data = _args_without_comment(data) 

1908 self.list_float_params[key] = [ 

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

1910 ] 

1911 elif key in special_keys: 

1912 if key == 'lreal': 

1913 val_char = data[2].lower().replace('.', '', 1) 

1914 if val_char.startswith('t'): 

1915 self.bool_params[key] = True 

1916 elif val_char.startswith('f'): 

1917 self.bool_params[key] = False 

1918 else: 

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

1920 

1921 # non-registered keys 

1922 elif data[2].lower() in {'t', 'true', '.true.'}: 

1923 self.bool_params[key] = True 

1924 elif data[2].lower() in {'f', 'false', '.false.'}: 

1925 self.bool_params[key] = False 

1926 elif data[2].isdigit(): 

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

1928 else: 

1929 try: 

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

1931 except ValueError: 

1932 self.string_params[key] = data[2] 

1933 

1934 except KeyError as exc: 

1935 raise KeyError( 

1936 f'Keyword "{key}" in INCAR is not known by calculator.' 

1937 ) from exc 

1938 except IndexError as exc: 

1939 raise IndexError( 

1940 f'Value missing for keyword "{key}".' 

1941 ) from exc 

1942 

1943 def read_kpoints(self, filename): 

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

1945 # If we used VASP builtin kspacing, 

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

1947 # Don't update kpts array 

1948 return 

1949 

1950 with open(filename) as fd: 

1951 lines = fd.readlines() 

1952 

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

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

1955 if ktype == 'g': 

1956 self.set(gamma=True) 

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

1958 elif ktype == 'a': 

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

1960 elif ktype == 'm': 

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

1962 else: 

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

1964 self.set(reciprocal=False) 

1965 else: 

1966 self.set(reciprocal=True) 

1967 kpts = np.array( 

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

1969 self.set(kpts=kpts) 

1970 

1971 def read_potcar(self, filename): 

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

1973 """ 

1974 

1975 # Search for key 'LEXCH' in POTCAR 

1976 xc_flag = None 

1977 with open(filename) as fd: 

1978 for line in fd: 

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

1980 if key == 'LEXCH': 

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

1982 break 

1983 

1984 if xc_flag is None: 

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

1986 

1987 # Values of parameter LEXCH and corresponding XC-functional 

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

1989 

1990 if xc_flag not in xc_dict.keys(): 

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

1992 ' LEXCH=%s' % xc_flag) 

1993 

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

1995 

1996 def todict(self): 

1997 """Returns a dictionary of all parameters 

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

1999 dict_list = [ 

2000 'float_params', 'exp_params', 'string_params', 'int_params', 

2001 'bool_params', 'list_bool_params', 'list_int_params', 

2002 'list_float_params', 'special_params', 'dict_params', 

2003 'input_params' 

2004 ] 

2005 dct = {} 

2006 for item in dict_list: 

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

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

2009 return dct 

2010 

2011 

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

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

2014 

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

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

2017 

2018 """ 

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

2020 if comment_locs == []: 

2021 return data 

2022 else: 

2023 return data[:min(comment_locs)] 

2024 

2025 

2026def _from_vasp_bool(x): 

2027 """Cast vasp boolean to Python bool 

2028 

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

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

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

2032 

2033 """ 

2034 assert isinstance(x, str) 

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

2036 return True 

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

2038 return False 

2039 else: 

2040 raise ValueError(f'Value "{x}" not recognized as bool') 

2041 

2042 

2043def _to_vasp_bool(x): 

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

2045 

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

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

2048 

2049 """ 

2050 if isinstance(x, str): 

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

2052 x = True 

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

2054 x = False 

2055 else: 

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

2057 assert isinstance(x, bool) 

2058 if x: 

2059 return '.TRUE.' 

2060 else: 

2061 return '.FALSE.' 

2062 

2063 

2064def open_potcar(filename): 

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

2066 """ 

2067 import gzip 

2068 if filename.endswith('R'): 

2069 return open(filename) 

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

2071 return gzip.open(filename) 

2072 else: 

2073 raise ValueError(f'Invalid POTCAR filename: "{filename}"') 

2074 

2075 

2076def read_potcar_numbers_of_electrons(file_obj): 

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

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

2079 nelect = [] 

2080 lines = file_obj.readlines() 

2081 for n, line in enumerate(lines): 

2082 if 'TITEL' in line: 

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

2084 valence = float( 

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

2086 nelect.append((symbol, valence)) 

2087 return nelect 

2088 

2089 

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

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

2092 

2093 Parameters: 

2094 atoms: Atoms object to be grouped 

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

2096 

2097 Returns: 

2098 Tuple of (symbols, symbolcount) 

2099 symbols: The unique symbols in the included list 

2100 symbolscount: Count of symbols in the included list 

2101 

2102 Example: 

2103 

2104 >>> from ase.build import bulk 

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

2106 >>> count_symbols(atoms) 

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

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

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

2110 """ 

2111 symbols = [] 

2112 symbolcount = {} 

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

2114 if m in exclude: 

2115 continue 

2116 if symbol not in symbols: 

2117 symbols.append(symbol) 

2118 symbolcount[symbol] = 1 

2119 else: 

2120 symbolcount[symbol] += 1 

2121 return symbols, symbolcount