Coverage for /builds/ericyuan00000/ase/ase/calculators/vasp/create_input.py: 68.28%

618 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2025-06-18 01:20 +0000

1# fmt: off 

2 

3# Copyright (C) 2008 CSC - Scientific Computing Ltd. 

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

5 

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

7Kitchin. The path of the directory containing the pseudopotential 

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

9by the environmental flag $VASP_PP_PATH. 

10 

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

12to a python script looking something like:: 

13 

14 import os 

15 exitcode = os.system('vasp') 

16 

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

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

19 

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

21""" 

22 

23import os 

24import shutil 

25import warnings 

26from os.path import isfile, islink, join 

27from typing import List, Sequence, Tuple 

28 

29import numpy as np 

30 

31import ase 

32from ase.calculators.calculator import kpts2ndarray 

33from ase.calculators.vasp.setups import get_default_setups 

34from ase.config import cfg 

35from ase.io.vasp_parsers.incar_writer import write_incar 

36 

37FLOAT_FORMAT = '5.6f' 

38EXP_FORMAT = '5.2e' 

39 

40 

41def check_ichain(ichain, ediffg, iopt): 

42 ichain_dct = {} 

43 if ichain > 0: 

44 ichain_dct['ibrion'] = 3 

45 ichain_dct['potim'] = 0.0 

46 if iopt is None: 

47 warnings.warn( 

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

49 ichain_dct['iopt'] = 1 

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

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

52 return ichain_dct 

53 

54 

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

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

57 magmom_dct = {} 

58 if magmom_input is not None: 

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

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

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

62 len(atoms), len(magmom_input)) 

63 raise ValueError(msg) 

64 

65 # Check if user remembered to specify ispin 

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

67 if not ispin: 

68 spinpol = True 

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

70 # matter 

71 magmom_dct['ispin'] = 2 

72 magmom = np.array(magmom_input) 

73 magmom = magmom[sorting] 

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

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

76 # but we could still be doing a spinpol calculation 

77 if not ispin: 

78 magmom_dct['ispin'] = 2 

79 # Write out initial magnetic moments 

80 magmom = atoms.get_initial_magnetic_moments()[sorting] 

81 # unpack magmom array if three components specified 

82 if magmom.ndim > 1: 

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

84 else: 

85 return spinpol, {} 

86 # Compactify the magmom list to symbol order 

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

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

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

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

91 else: 

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

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

94 for mom in lst]) 

95 magmom_dct['magmom'] = line 

96 return spinpol, magmom_dct 

97 

98 

99def set_ldau(ldau_param, luj_params, symbol_count): 

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

101 ldau_dct = {} 

102 if ldau_param is None: 

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

104 llist = [] 

105 ulist = [] 

106 jlist = [] 

107 for symbol in symbol_count: 

108 # default: No +U 

109 luj = luj_params.get( 

110 symbol[0], 

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

112 ) 

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

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

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

116 ldau_dct['ldaul'] = llist 

117 ldau_dct['ldauu'] = ulist 

118 ldau_dct['ldauj'] = jlist 

119 return ldau_dct 

120 

121 

122def test_nelect_charge_compitability(nelect, charge, nelect_from_ppp): 

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

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

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

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

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

128 nelect_from_charge = nelect_from_ppp - charge 

129 if nelect and nelect != nelect_from_charge: 

130 raise ValueError('incompatible input parameters: ' 

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

132 '(neutral nelect is ' 

133 f'{nelect_from_ppp})') 

134 print(nelect_from_charge) 

135 return nelect_from_charge 

136 else: 

137 return nelect 

138 

139 

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

141 """ 

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

143 

144 Parameters 

145 ---------- 

146 setup : [str, dict] 

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

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

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

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

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

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

153 available. The default is 'minimal 

154 

155 Returns 

156 ------- 

157 setups : dict 

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

159 as values. 

160 special_setups : list 

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

162 """ 

163 special_setups = [] 

164 

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

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

167 setups_defaults = get_default_setups() 

168 

169 # Default to minimal basis 

170 if setup is None: 

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

172 

173 # String shortcuts are initialised to dict form 

174 elif isinstance(setup, str): 

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

176 setup = {'base': setup} 

177 

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

179 if 'base' in setup: 

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

181 else: 

182 setups = {} 

183 

184 # Override defaults with user-defined setups 

185 if setup is not None: 

186 setups.update(setup) 

187 

188 for m in setups: 

189 try: 

190 special_setups.append(int(m)) 

191 except ValueError: 

192 pass 

193 return setups, special_setups 

194 

195 

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

197 tokens = [] 

198 append = tokens.append 

199 

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

201 

202 if isinstance(kpts, dict): 

203 kpts = kpts2ndarray(kpts, atoms=atoms) 

204 reciprocal = True 

205 

206 shape = np.array(kpts).shape 

207 

208 # Wrap scalar in list if necessary 

209 if shape == (): 

210 kpts = [kpts] 

211 shape = (1, ) 

212 

213 if len(shape) == 1: 

214 append('0\n') 

215 if shape == (1, ): 

216 append('Auto\n') 

217 elif gamma: 

218 append('Gamma\n') 

219 else: 

220 append('Monkhorst-Pack\n') 

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

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

223 elif len(shape) == 2: 

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

225 if reciprocal: 

226 append('Reciprocal\n') 

227 else: 

228 append('Cartesian\n') 

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

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

231 if shape[1] == 4: 

232 append('\n') 

233 elif shape[1] == 3: 

234 append('1.0 \n') 

235 return ''.join(tokens) 

236 

237 

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

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

240 

241float_keys = [ 

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

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

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

245 'aldac', # Fraction of LDA correlation energy 

246 'amin', # 

247 'amix', # 

248 'amix_mag', # 

249 'bmix', # tags for mixing 

250 'bmix_mag', # 

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

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

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

254 # (EDIFF/N-BANDS/4) 

255 'efield', # applied electrostatic field 

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

257 'emin', # 

258 'enaug', # Density cutoff 

259 'encut', # Planewave cutoff 

260 'encutgw', # energy cutoff for response function 

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

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

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

264 # file is not present. KSPACING is the smallest 

265 # allowed spacing between k-points in units of 

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

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

268 'nelect', # total number of electrons 

269 'param1', # Exchange parameter 

270 'param2', # Exchange parameter 

271 'pomass', # mass of ions in am 

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

273 # pstress 

274 'sigma', # broadening in eV 

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

276 'spring', # spring constant for NEB 

277 'time', # special control tag 

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

279 'zab_vdw', # vdW-DF parameter 

280 'zval', # ionic valence 

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

282 # group at UT Austin 

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

284 'ddr', # (DdR) dimer separation 

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

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

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

288 'sltol', # convergence ratio for minimum eigenvalue 

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

290 # size when translating 

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

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

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

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

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

296 'ftimemax', # Max time step 

297 'ftimedec', # Factor to dec. dt 

298 'ftimeinc', # Factor to inc. dt 

299 'falpha', # Parameter for velocity damping 

300 'falphadec', # Factor to dec. alpha 

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

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

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

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

305 # correction 

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

307 # and Scheffler's DFT-TS dispersion corrections 

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

309 # Grimme's DFT-D3 dispersion correction 

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

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

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

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

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

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

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

317 'eb_k', # solvent permitivity in Vaspsol 

318 'tau', # surface tension parameter in Vaspsol 

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

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

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

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

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

324 'tebeg', # 

325 'teend', # temperature during run 

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

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

328 'auger_ecblo', # Undocumented parameter for Auger calculations 

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

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

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

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

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

334 'auger_occ_fac_eeh', # Undocumented parameter for Auger calculations 

335 'auger_occ_fac_ehh', # Undocumented parameter for Auger calculations 

336 'auger_temp', # Temperature for Auger calculation 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

373 'deg_threshold', # Degeneracy threshold 

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

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

376 'rtime', # Undocumented parameter 

377 'wplasma', # Undocumented parameter 

378 'wplasmai', # Undocumented parameter 

379 'dfield', # Undocumented parameter 

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

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

382 'encutlf', # Undocumented parameter 

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

384 'dimer_dist', # Distance between dimer images 

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

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

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

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

389 'shaketol', # Tolerance for SHAKE algorithm 

390 'shaketolsoft', # Soft tolerance for SHAKE algorithm 

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

392 'hills_stride', # Undocumented metadynamics parameter 

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

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

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

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

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

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

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

400 'dvvdelta0', # Undocumented parameter 

401 'dvvvnorm0', # Undocumented parameter 

402 'dvvminpotim', # Undocumented parameter 

403 'dvvmaxpotim', # Undocumented parameter 

404 'enchg', # Undocumented charge fitting parameter 

405 'tau0', # Undocumented charge fitting parameter 

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

407 'param3', # Undocumented HF parameter 

408 'model_eps0', # Undocumented HF parameter 

409 'model_alpha', # Undocumented HF parameter 

410 'qmaxfockae', # Undocumented HF parameter 

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

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

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

414 'encutsubrotscf', # Undocumented subspace rotation SCF parameter 

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

416 'wc', # Undocumented mixing parameter 

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

418 'scalee', # Undocumented parameter 

419 'eref', # Reference energy 

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

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

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

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

424 'lj_radius', # Undocumented classical vdW parameter 

425 'lj_epsilon', # Undocumented classical vdW parameter 

426 'lj_sigma', # Undocumented classical vdW parameter 

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

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

429 'hitoler', # Iterative Hirschfeld partitioning tolerance 

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

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

432 'maxpwamp', # Undocumented HF parameter 

433 'vcutoff', # Undocumented parameter 

434 'mdtemp', # Temperature for AIMD 

435 'mdgamma', # Undocumented AIMD parameter 

436 'mdalpha', # Undocumented AIMD parameter 

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

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

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

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

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

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

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

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

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

446 'qtpz', # Temperature (instanton) 

447 'qftol', # Tolerance (instanton) 

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

449] 

450 

451exp_keys = [ 

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

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

454 'symprec', # precession in symmetry routines 

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

456 # group at UT Austin 

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

458] 

459 

460string_keys = [ 

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

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

463 'metagga', # 

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

465 'system', # name of System 

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

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

468 'localized_basis', # Basis to use in CRPA 

469 'proutine', # Select profiling routine 

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

471] 

472 

473int_keys = [ 

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

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

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

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

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

479 'imix', # specifies density mixing 

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

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

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

483 'ispin', # spin-polarized calculation 

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

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

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

487 'kpar', # k-point parallelization paramater 

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

489 # written 

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

491 'lmaxmix', # 

492 'lorbit', # create PROOUT 

493 'maxmix', # 

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

495 'ngxf', # FFT mesh for charges x 

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

497 'ngyf', # FFT mesh for charges y 

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

499 'ngzf', # FFT mesh for charges z 

500 'nbands', # Number of bands 

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

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

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

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

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

506 'nelmin', 

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

508 # finite differences 

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

510 # nkredx=nkredy=nkredz 

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

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

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

514 'nomega', # number of frequency points 

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

516 'npar', # parallelization over bands 

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

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

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

520 'vdwgr', # extra keyword for Andris program 

521 'vdwrn', # extra keyword for Andris program 

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

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

524 # group at UT Austin 

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

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

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

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

529 # and potim = 0.0 

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

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

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

533 'icorelevel', # core level shifts 

534 'clnt', # species index 

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

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

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

538 'nbandsgw', # Number of bands for GW 

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

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

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

542 # by npar 

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

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

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

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

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

548 # response function calc. 

549 'taupar', 

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

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

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

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

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

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

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

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

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

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

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

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

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

563 'ibse', # Type of BSE calculation 

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

565 'naturalo', # Use NATURALO (?) 

566 'nbandsexact', # Undocumented parameter 

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

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

569 'omegagrid', # Undocumented parameter 

570 'telescope', # Undocumented parameter 

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

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

573 'dim', # Undocumented parameter 

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

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

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

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

578 'lmaxmp2', # Undocumented parameter 

579 'switch', # Undocumented dimer parameter 

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

581 'engine', # Undocumented dimer parameter 

582 'restartcg', # Undocumented dimer parameter 

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

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

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

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

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

588 'hills_maxstride', # Undocumented metadynamics parameter 

589 'dvvehistory', # Undocumented parameter 

590 'ipead', # Undocumented parameter 

591 'ngaus', # Undocumented charge fitting parameter 

592 'exxoep', # Undocumented HF parameter 

593 'fourorbit', # Undocumented HF parameter 

594 'model_gw', # Undocumented HF parameter 

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

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

597 'lmaxfockae', # Undocumented HF parameter 

598 'nmaxfockae', # Undocumented HF parameter 

599 'nblock_fock', # Undocumented HF parameter 

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

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

602 'mremove', # Undocumented mixing parameter 

603 'inimix', # Undocumented mixing parameter 

604 'mixpre', # Undocumented mixing parameter 

605 'nelmall', # Undocumented parameter 

606 'nblock', # How frequently to write data 

607 'kblock', # How frequently to write data 

608 'npaco', # Undocumented pair correlation function parameter 

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

610 'irestart', # Undocumented parameter 

611 'nreboot', # Undocumented parameter 

612 'nmin', # Undocumented parameter 

613 'nlspline', # Undocumented parameter 

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

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

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

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

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

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

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

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

622 'nbands_out', # Undocumented QP parameter 

623 'kpts_out', # Undocumented QP parameter 

624 'isp_out', # Undocumented QP parameter 

625 'nomega_out', # Undocumented QP parameter 

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

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

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

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

630 'ncore_in_image1', # Undocumented parameter 

631 'kimages', # Undocumented parameter 

632 'ncores_per_band', # Undocumented parameter 

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

634 'ncrpalow', # Undocumented CRPA parameter 

635 'ncrpahigh', # Undocumented CRPA parameter 

636 'nwlow', # Undocumented parameter 

637 'nwhigh', # Undocumented parameter 

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

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

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

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

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

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

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

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

646] 

647 

648bool_keys = [ 

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

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

651 # centred at the $\Gamma$ 

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

653 # (KGAMMA=.TRUE.) 

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

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

656 # VASP.5.X) 

657 'lasync', # overlap communcation with calculations 

658 'lcharg', # 

659 'lcorr', # Harris-correction to forces 

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

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

662 'ldipol', # potential correction mode 

663 'lelf', # create ELFCAR 

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

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

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

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

668 # density 

669 'lplane', # parallelisation over the FFT grid 

670 'lscalapack', # switch off scaLAPACK 

671 'lscalu', # switch of LU decomposition 

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

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

674 'lthomas', # 

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

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

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

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

679 'lwave', # 

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

681 # group at UT Austin 

682 'lclimb', # Turn on CI-NEB 

683 'ltangentold', # Old central difference tangent 

684 'ldneb', # Turn on modified double nudging 

685 'lnebcell', # Turn on SS-NEB 

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

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

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

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

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

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

692 # tensors (vasp 5.2) 

693 'lvdw', # Turns on dispersion correction 

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

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

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

697 # polarizability 

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

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

700 'lsorbit', # Enable spin-orbit coupling 

701 'lsol', # turn on solvation for Vaspsol 

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

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

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

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

706 'interactive', # Enables interactive calculation for VaspInteractive 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

737 'lmixtau', # Undocumented MetaGGA parameter 

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

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

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

741 'lnabla', # Undocumented parameter 

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

743 'lvel', # Undocumented parameter 

744 'lrpaforce', # Calculate RPA forces 

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

746 'ladder', # Use ladder diagrams 

747 'lfxc', # Use approximate ladder diagrams 

748 'lrsrpa', # Undocumented parameter 

749 'lsingles', # Calculate HF singles 

750 'lfermigw', # Iterate Fermi level 

751 'ltcte', # Undocumented parameter 

752 'ltete', # Undocumented parameter 

753 'ltriplet', # Undocumented parameter 

754 'lfxceps', # Undocumented parameter 

755 'lfxheg', # Undocumented parameter 

756 'l2order', # Undocumented parameter 

757 'lmp2lt', # Undocumented parameter 

758 'lgwlf', # Undocumented parameter 

759 'lusew', # Undocumented parameter 

760 'selfenergy', # Undocumented parameter 

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

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

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

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

765 'fletcher_reeves', # Undocumented dimer parameter 

766 'lidm_selective', # Undocumented dimer parameter 

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

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

769 'dvvminus', # Undocumented parameter 

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

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

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

773 'lchgfit', # Turn on charge fitting 

774 'lgausrc', # Undocumented charge fitting parameter 

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

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

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

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

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

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

781 'shiftred', # Undocumented HF parameter 

782 'hfkident', # Undocumented HF parameter 

783 'oddonly', # Undocumented HF parameter 

784 'evenonly', # Undocumented HF parameter 

785 'lfockaedft', # Undocumented HF parameter 

786 'lsubrot', # Enable subspace rotation diagonalization 

787 'mixfirst', # Mix before diagonalization 

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

789 'lcompat', # Enable "full compatibility" 

790 'lmusic', # "Joke" parameter 

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

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

793 'lorbitalreal', # Undocumented parameter 

794 'lmetagga', # Undocumented parameter 

795 'lspiral', # Undocumented parameter 

796 'lzeroz', # Undocumented parameter 

797 'lmono', # Enable "monopole" corrections 

798 'lrelcore', # Perform relaxed core calculation 

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

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

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

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

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

804 'lrelvol', # Undocumented classical vdW parameter 

805 'lj_only', # Undocumented classical vdW parameter 

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

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

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

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

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

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

812 'lvdw_relvolone', # Undocumented classical vdW parameter 

813 'lberry', # Enable Berry-phase calculation 

814 'lpade_fit', # Undocumented QP parameter 

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

816 'l_wr_moments', # Undocumented parameter 

817 'l_wr_density', # Undocumented parameter 

818 'lkotani', # Undocumented parameter 

819 'ldyson', # Undocumented parameter 

820 'laddherm', # Undocumented parameter 

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

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

823 'ldisentangle', # Disentangle bands in CRPA 

824 'lweighted', # "Weighted" CRPA approach 

825 'luseorth_lcaos', # Use orthogonalized LCAOs in CRPA 

826 'lfrpa', # Use full RPA in CRPA 

827 'lregularize', # Regularize projectors in CRPA 

828 'ldrude', # Include Drude term in CRPA 

829 'ldmatrix', # Undocumented parameter 

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

831 'lhyperfine', # Enable Hyperfine calculation 

832 'lwannier', # Enable Wannier interface 

833 'localize', # Undocumented Wannier parameter 

834 'lintpol_wpot', # Interpolate WPOT for Wannier 

835 'lintpol_orb', # Interpolate orbitals for Wannier 

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

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

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

839 'lintpol_velocity', # Interpolate electron velocity for Wannier 

840 'lintpol_conductivity', # Interpolate conductivity for Wannier 

841 'lwannierinterpol', # Undocumented Wannier parameter 

842 'wanproj', # Undocumented Wannier parameter 

843 'lorbmom', # Undocumented LDA+U parameter 

844 'lwannier90_run', # Undocumented WANNIER90 parameter 

845 'lwrite_wanproj', # Write UWAN files for WANNIER90 

846 'lwrite_unk', # Write UNK files for WANNIER90 

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

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

849 'lrhfatm', # Undocumented HF parameter 

850 'lvpot', # Calculate unscreened potential 

851 'lwpot', # Calculate screened potential 

852 'lwswq', # Undocumented parameter 

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

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

855 'qdo_ins', # Find instanton 

856 'qdo_pre', # Calculate prefactor (instanton) 

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

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

859 'lnbo', # Enable NBO analysis 

860] 

861 

862list_int_keys = [ 

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

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

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

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

867 # (Bucko) 

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

869 'auger_bmax_eeh', # 4 ints | calculations 

870 'auger_bmin_ehh', # 4 ints | 

871 'auger_bmax_ehh', # 4 ints | 

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

873 'kpoint_bse', # 4 ints | Undocumented parameter 

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

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

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

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

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

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

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

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

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

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

884] 

885 

886list_bool_keys = [ 

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

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

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

890] 

891 

892list_float_keys = [ 

893 'dipol', # center of cell for dipol 

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

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

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

897 'magmom', # initial magnetic moments 

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

899 'rwigs', # Wigner-Seitz radii 

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

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

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

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

904 # when a calculation is set up 

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

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

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

908 # (DFT-TS) 

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

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

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

912 # (DFT-TS) 

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

914 # species (DFT-TS) 

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

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

917 'auger_emax_eeh', # 4 floats | calculations 

918 'auger_emin_ehh', # 4 floats | 

919 'auger_emax_ehh', # 4 floats | 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

952 'qspiral', # 3 floats | Undocumented parameter 

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

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

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

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

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

958 'ofield_k', # 3 floats | Undocumented parameter 

959 'paripot', # ? floats | Undocumented parameter 

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

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

962] 

963 

964special_keys = [ 

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

966] 

967 

968dict_keys = [ 

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

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

971] 

972 

973keys: List[str] = [ 

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

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

976 # 'WEIMIN, EBREAK, DEPER special control tags 

977] 

978 

979 

980class GenerateVaspInput: 

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

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

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

984 xc_defaults = { 

985 'lda': { 

986 'pp': 'LDA' 

987 }, 

988 # GGAs 

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

990 'pp': 'PBE', 

991 'gga': 'B5', 

992 'aldax': 1.00, 

993 'aggax': 1.00, 

994 'aggac': 1.00, 

995 'aldac': 0.00 

996 }, 

997 'pw91': { 

998 'pp': 'PW91', 

999 'gga': '91' 

1000 }, 

1001 'pbe': { 

1002 'pp': 'PBE', 

1003 'gga': 'PE' 

1004 }, 

1005 'pbesol': { 

1006 'gga': 'PS' 

1007 }, 

1008 'revpbe': { 

1009 'gga': 'RE' 

1010 }, 

1011 'rpbe': { 

1012 'gga': 'RP' 

1013 }, 

1014 'am05': { 

1015 'gga': 'AM' 

1016 }, 

1017 # Meta-GGAs 

1018 'tpss': { 

1019 'metagga': 'TPSS' 

1020 }, 

1021 'revtpss': { 

1022 'metagga': 'RTPSS' 

1023 }, 

1024 'm06l': { 

1025 'metagga': 'M06L' 

1026 }, 

1027 'ms0': { 

1028 'metagga': 'MS0' 

1029 }, 

1030 'ms1': { 

1031 'metagga': 'MS1' 

1032 }, 

1033 'ms2': { 

1034 'metagga': 'MS2' 

1035 }, 

1036 'scan': { 

1037 'metagga': 'SCAN' 

1038 }, 

1039 'rscan': { 

1040 'metagga': 'RSCAN' 

1041 }, 

1042 'r2scan': { 

1043 'metagga': 'R2SCAN' 

1044 }, 

1045 'scan-rvv10': { 

1046 'metagga': 'SCAN', 

1047 'luse_vdw': True, 

1048 'bparam': 15.7 

1049 }, 

1050 'mbj': { 

1051 # Modified Becke-Johnson 

1052 'metagga': 'MBJ', 

1053 }, 

1054 'tb09': { 

1055 # Alias for MBJ 

1056 'metagga': 'MBJ', 

1057 }, 

1058 # vdW-DFs 

1059 'vdw-df': { 

1060 'gga': 'RE', 

1061 'luse_vdw': True, 

1062 'aggac': 0. 

1063 }, 

1064 'vdw-df-cx': { 

1065 'gga': 'CX', 

1066 'luse_vdw': True, 

1067 'aggac': 0. 

1068 }, 

1069 'vdw-df-cx0p': { 

1070 'gga': 'CX', 

1071 'luse_vdw': True, 

1072 'aggac': 0., 

1073 'lhfcalc': True, 

1074 'aexx': 0.2, 

1075 'aggax': 0.8 

1076 }, 

1077 'optpbe-vdw': { 

1078 'gga': 'OR', 

1079 'luse_vdw': True, 

1080 'aggac': 0.0 

1081 }, 

1082 'optb88-vdw': { 

1083 'gga': 'BO', 

1084 'luse_vdw': True, 

1085 'aggac': 0.0, 

1086 'param1': 1.1 / 6.0, 

1087 'param2': 0.22 

1088 }, 

1089 'optb86b-vdw': { 

1090 'gga': 'MK', 

1091 'luse_vdw': True, 

1092 'aggac': 0.0, 

1093 'param1': 0.1234, 

1094 'param2': 1.0 

1095 }, 

1096 'vdw-df2': { 

1097 'gga': 'ML', 

1098 'luse_vdw': True, 

1099 'aggac': 0.0, 

1100 'zab_vdw': -1.8867 

1101 }, 

1102 'rev-vdw-df2': { 

1103 'gga': 'MK', 

1104 'luse_vdw': True, 

1105 'param1': 0.1234, 

1106 'param2': 0.711357, 

1107 'zab_vdw': -1.8867, 

1108 'aggac': 0.0 

1109 }, 

1110 'beef-vdw': { 

1111 'gga': 'BF', 

1112 'luse_vdw': True, 

1113 'zab_vdw': -1.8867 

1114 }, 

1115 # Hartree-Fock and hybrids 

1116 'hf': { 

1117 'lhfcalc': True, 

1118 'aexx': 1.0, 

1119 'aldac': 0.0, 

1120 'aggac': 0.0 

1121 }, 

1122 'b3lyp': { 

1123 'gga': 'B3', 

1124 'lhfcalc': True, 

1125 'aexx': 0.2, 

1126 'aggax': 0.72, 

1127 'aggac': 0.81, 

1128 'aldac': 0.19 

1129 }, 

1130 'pbe0': { 

1131 'gga': 'PE', 

1132 'lhfcalc': True 

1133 }, 

1134 'hse03': { 

1135 'gga': 'PE', 

1136 'lhfcalc': True, 

1137 'hfscreen': 0.3 

1138 }, 

1139 'hse06': { 

1140 'gga': 'PE', 

1141 'lhfcalc': True, 

1142 'hfscreen': 0.2 

1143 }, 

1144 'hsesol': { 

1145 'gga': 'PS', 

1146 'lhfcalc': True, 

1147 'hfscreen': 0.2 

1148 }, 

1149 # MN-VFM functionals 

1150 'sogga': { 

1151 'gga': 'SA' 

1152 }, 

1153 'sogga11': { 

1154 'gga': 'S1' 

1155 }, 

1156 'sogga11-x': { 

1157 'gga': 'SX', 

1158 'lhfcalc': True, 

1159 'aexx': 0.401 

1160 }, 

1161 'n12': { 

1162 'gga': 'N2' 

1163 }, 

1164 'n12-sx': { 

1165 'gga': 'NX', 

1166 'lhfcalc': True, 

1167 'lhfscreen': 0.2 

1168 }, 

1169 'mn12l': { 

1170 'metagga': 'MN12L' 

1171 }, 

1172 'gam': { 

1173 'gga': 'GA' 

1174 }, 

1175 'mn15l': { 

1176 'metagga': 'MN15L' 

1177 }, 

1178 'hle17': { 

1179 'metagga': 'HLE17' 

1180 }, 

1181 'revm06l': { 

1182 'metagga': 'revM06L' 

1183 }, 

1184 'm06sx': { 

1185 'metagga': 'M06SX', 

1186 'lhfcalc': True, 

1187 'hfscreen': 0.189, 

1188 'aexx': 0.335 

1189 } 

1190 } 

1191 

1192 # environment variable for PP paths 

1193 VASP_PP_PATH = 'VASP_PP_PATH' 

1194 

1195 def __init__(self, restart=None): 

1196 self.float_params = {} 

1197 self.exp_params = {} 

1198 self.string_params = {} 

1199 self.int_params = {} 

1200 self.bool_params = {} 

1201 self.list_bool_params = {} 

1202 self.list_int_params = {} 

1203 self.list_float_params = {} 

1204 self.special_params = {} 

1205 self.dict_params = {} 

1206 self.atoms = None 

1207 for key in float_keys: 

1208 self.float_params[key] = None 

1209 for key in exp_keys: 

1210 self.exp_params[key] = None 

1211 for key in string_keys: 

1212 self.string_params[key] = None 

1213 for key in int_keys: 

1214 self.int_params[key] = None 

1215 for key in bool_keys: 

1216 self.bool_params[key] = None 

1217 for key in list_bool_keys: 

1218 self.list_bool_params[key] = None 

1219 for key in list_int_keys: 

1220 self.list_int_params[key] = None 

1221 for key in list_float_keys: 

1222 self.list_float_params[key] = None 

1223 for key in special_keys: 

1224 self.special_params[key] = None 

1225 for key in dict_keys: 

1226 self.dict_params[key] = None 

1227 

1228 # Initialize internal dictionary of input parameters which are 

1229 # not regular VASP keys 

1230 self.input_params = { 

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

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

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

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

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

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

1237 'gamma': False, 

1238 # number of points between points in band structures: 

1239 'kpts_nintersections': None, 

1240 # Option to write explicit k-points in units 

1241 # of reciprocal lattice vectors: 

1242 'reciprocal': False, 

1243 # Switch to disable writing constraints to POSCAR 

1244 'ignore_constraints': False, 

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

1246 'charge': None, 

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

1248 # with the sign flipped 

1249 'net_charge': None, 

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

1251 'custom': {}, 

1252 } 

1253 # warning message for pw91 

1254 self.pw91_warning_msg =\ 

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

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

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

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

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

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

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

1262 "energies given by the POTCAR file." 

1263 

1264 def set_xc_params(self, xc): 

1265 """Set parameters corresponding to XC functional""" 

1266 xc = xc.lower() 

1267 if xc is None: 

1268 pass 

1269 elif xc not in self.xc_defaults: 

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

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

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

1273 else: 

1274 # print future warning in case pw91 is selected: 

1275 if xc == 'pw91': 

1276 warnings.warn( 

1277 self.pw91_warning_msg, FutureWarning 

1278 ) 

1279 # XC defaults to PBE pseudopotentials 

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

1281 self.set(pp='PBE') 

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

1283 

1284 def set(self, **kwargs): 

1285 

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

1287 and ('ldau_luj' in kwargs)): 

1288 raise NotImplementedError( 

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

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

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

1292 'chemical species in the atoms object. ' 

1293 'For example for a water molecule:' 

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

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

1296 

1297 if 'xc' in kwargs: 

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

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

1300 if key in self.float_params: 

1301 self.float_params[key] = value 

1302 elif key in self.exp_params: 

1303 self.exp_params[key] = value 

1304 elif key in self.string_params: 

1305 self.string_params[key] = value 

1306 elif key in self.int_params: 

1307 self.int_params[key] = value 

1308 elif key in self.bool_params: 

1309 self.bool_params[key] = value 

1310 elif key in self.list_bool_params: 

1311 self.list_bool_params[key] = value 

1312 elif key in self.list_int_params: 

1313 self.list_int_params[key] = value 

1314 elif key in self.list_float_params: 

1315 self.list_float_params[key] = value 

1316 elif key in self.special_params: 

1317 self.special_params[key] = value 

1318 elif key in self.dict_params: 

1319 self.dict_params[key] = value 

1320 elif key in self.input_params: 

1321 self.input_params[key] = value 

1322 elif isinstance(value, str): 

1323 self.string_params[key] = value 

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

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

1326 elif isinstance(value, bool): 

1327 self.bool_params[key] = value 

1328 elif isinstance(value, int): 

1329 self.int_params[key] = value 

1330 elif isinstance(value, float): 

1331 self.float_params[key] = value 

1332 elif isinstance(value, list): 

1333 if len(value) == 0: 

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

1335 raise ValueError(msg) 

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

1337 self.list_bool_params[key] = value 

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

1339 self.list_int_params[key] = value 

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

1341 self.list_float_params[key] = value 

1342 else: 

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

1344 raise TypeError(msg) 

1345 else: 

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

1347 raise TypeError(msg) 

1348 

1349 def check_xc(self): 

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

1351 

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

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

1354 """ 

1355 

1356 p = self.input_params 

1357 

1358 # There is no way to correctly guess the desired 

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

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

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

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

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

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

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

1366 warnings.warn( 

1367 self.pw91_warning_msg, FutureWarning 

1368 ) 

1369 

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

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

1372 else: 

1373 raise NotImplementedError( 

1374 "Unable to guess the desired set of pseudopotential" 

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

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

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

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

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

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

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

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

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

1384 "accepted.\n") 

1385 

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

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

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

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

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

1391 "really what you intended!" 

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

1393 

1394 def _make_sort( 

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

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

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

1398 

1399 # Create sorting list 

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

1401 srt.extend(special_setups) 

1402 

1403 for symbol in symbols: 

1404 for m, atom in enumerate(atoms): 

1405 if m in special_setups: 

1406 continue 

1407 if atom.symbol == symbol: 

1408 srt.append(m) 

1409 # Create the resorting list 

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

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

1412 resrt[srt[n]] = n 

1413 return srt, resrt 

1414 

1415 def _set_spinpol(self, atoms): 

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

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

1418 else: 

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

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

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

1422 

1423 def _build_pp_list(self, 

1424 atoms, 

1425 setups=None, 

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

1427 """Build the pseudopotential lists""" 

1428 

1429 p = self.input_params 

1430 

1431 if setups is None: 

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

1433 

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

1435 

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

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

1438 ('pbe', 'potpaw_PBE')): 

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

1440 break 

1441 else: 

1442 pp_folder = p['pp'] 

1443 

1444 if self.VASP_PP_PATH in cfg: 

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

1446 else: 

1447 pppaths = [] 

1448 ppp_list = [] 

1449 # Setting the pseudopotentials, first special setups and 

1450 # then according to symbols 

1451 for m in special_setups: 

1452 if m in setups: 

1453 special_setup_index = m 

1454 elif str(m) in setups: 

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

1456 else: 

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

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

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

1460 for path in pppaths: 

1461 filename = join(path, potcar) 

1462 

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

1464 ppp_list.append(filename) 

1465 break 

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

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

1468 break 

1469 else: 

1470 symbol = atoms.symbols[m] 

1471 msg = """Looking for {}. 

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

1473 potcar, symbol, setups[special_setup_index]) 

1474 raise RuntimeError(msg) 

1475 

1476 for symbol in symbols: 

1477 try: 

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

1479 except (TypeError, KeyError): 

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

1481 for path in pppaths: 

1482 filename = join(path, potcar) 

1483 

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

1485 ppp_list.append(filename) 

1486 break 

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

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

1489 break 

1490 else: 

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

1492 The pseudopotentials are expected to be in: 

1493 LDA: $VASP_PP_PATH/potpaw/ 

1494 PBE: $VASP_PP_PATH/potpaw_PBE/ 

1495 PW91: $VASP_PP_PATH/potpaw_GGA/ 

1496 

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

1498 raise RuntimeError(msg) 

1499 return ppp_list 

1500 

1501 def initialize(self, atoms): 

1502 """Initialize a VASP calculation 

1503 

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

1505 User should specify the PATH 

1506 to the pseudopotentials in VASP_PP_PATH environment variable 

1507 

1508 The pseudopotentials are expected to be in: 

1509 LDA: $VASP_PP_PATH/potpaw/ 

1510 PBE: $VASP_PP_PATH/potpaw_PBE/ 

1511 PW91: $VASP_PP_PATH/potpaw_GGA/ 

1512 

1513 if your pseudopotentials are somewhere else, or named 

1514 differently you may make symlinks at the paths above that 

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

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

1517 """ 

1518 

1519 self.check_xc() 

1520 self.atoms = atoms 

1521 self.all_symbols = atoms.get_chemical_symbols() 

1522 self.natoms = len(atoms) 

1523 

1524 self._set_spinpol(atoms) 

1525 

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

1527 

1528 # Determine the number of atoms of each atomic species 

1529 # sorted after atomic species 

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

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

1532 special_setups=special_setups) 

1533 

1534 self.atoms_sorted = atoms[self.sort] 

1535 

1536 # Check if the necessary POTCAR files exists and 

1537 # create a list of their paths. 

1538 atomtypes = atoms.get_chemical_symbols() 

1539 self.symbol_count = [] 

1540 for m in special_setups: 

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

1542 for m in symbols: 

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

1544 

1545 # create pseudopotential list 

1546 self.ppp_list = self._build_pp_list(atoms, 

1547 setups=setups, 

1548 special_setups=special_setups) 

1549 

1550 self.converged = None 

1551 self.setups_changed = None 

1552 

1553 def default_nelect_from_ppp(self): 

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

1555 

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

1557 """ 

1558 symbol_valences = [] 

1559 for filename in self.ppp_list: 

1560 with open_potcar(filename=filename) as ppp_file: 

1561 r = read_potcar_numbers_of_electrons(ppp_file) 

1562 symbol_valences.extend(r) 

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

1564 default_nelect = 0 

1565 for ((symbol1, count), 

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

1567 assert symbol1 == symbol2 

1568 default_nelect += count * valence 

1569 return default_nelect 

1570 

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

1572 from ase.io.vasp import write_vasp 

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

1574 self.atoms_sorted, 

1575 symbol_count=self.symbol_count, 

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

1577 self.write_incar(atoms, directory=directory) 

1578 self.write_potcar(directory=directory) 

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

1580 self.write_sort_file(directory=directory) 

1581 self.copy_vdw_kernel(directory=directory) 

1582 

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

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

1585 Set ASE_VASP_VDW environment variable to the vdw_kernel.bindat 

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

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

1588 

1589 vdw_env = 'ASE_VASP_VDW' 

1590 kernel = 'vdw_kernel.bindat' 

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

1592 

1593 # No need to copy the file again 

1594 if isfile(dst): 

1595 return 

1596 

1597 if self.bool_params['luse_vdw']: 

1598 src = None 

1599 if vdw_env in cfg: 

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

1601 

1602 if not src or not isfile(src): 

1603 warnings.warn( 

1604 ('vdW has been enabled, however no' 

1605 ' location for the {} file' 

1606 ' has been specified.' 

1607 ' Set {} environment variable to' 

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

1609 else: 

1610 shutil.copyfile(src, dst) 

1611 

1612 def clean(self): 

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

1614 

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

1616 method is called. 

1617 

1618 """ 

1619 files = [ 

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

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

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

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

1624 ] 

1625 for f in files: 

1626 try: 

1627 os.remove(f) 

1628 except OSError: 

1629 pass 

1630 

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

1632 """Writes the INCAR file.""" 

1633 incar_params = {} 

1634 

1635 # float params 

1636 float_dct = { 

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

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

1639 if val is not None 

1640 } 

1641 

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

1643 'charge'] is not None: 

1644 nelect_val = test_nelect_charge_compitability( 

1645 self.float_params['nelect'], 

1646 self.input_params['charge'], 

1647 self.default_nelect_from_ppp()) 

1648 if nelect_val: 

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

1650 incar_params.update(float_dct) 

1651 

1652 # exp params 

1653 exp_dct = { 

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

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

1656 if val is not None 

1657 } 

1658 incar_params.update(exp_dct) 

1659 

1660 # string_params 

1661 string_dct = { 

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

1663 None 

1664 } 

1665 incar_params.update(string_dct) 

1666 

1667 # int params 

1668 int_dct = { 

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

1670 } 

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

1672 ichain_dict = check_ichain( 

1673 ichain=int_dct['ichain'], 

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

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

1676 ) 

1677 int_dct.update(ichain_dict) 

1678 incar_params.update(int_dct) 

1679 

1680 # list_bool_params 

1681 bool_dct = { 

1682 key: val 

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

1684 if val is not None 

1685 } 

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

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

1688 incar_params.update(bool_dct) 

1689 

1690 # list_int_params 

1691 int_dct = { 

1692 key: val 

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

1694 if val is not None 

1695 } 

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

1697 'ldau_luj'] is not None: 

1698 del int_dct['ldaul'] 

1699 incar_params.update(int_dct) 

1700 

1701 # list_float_params 

1702 float_dct = { 

1703 key: val 

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

1705 if val is not None 

1706 } 

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

1708 'ldau_luj'] is not None: 

1709 del float_dct['ldauu'] 

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

1711 'ldau_luj'] is not None: 

1712 del float_dct['ldauj'] 

1713 incar_params.update(float_dct) 

1714 

1715 # bool params 

1716 bool_dct = { 

1717 key: _to_vasp_bool(val) 

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

1719 if val is not None 

1720 } 

1721 incar_params.update(bool_dct) 

1722 

1723 # special params 

1724 special_dct = { 

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

1726 None 

1727 } 

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

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

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

1731 incar_params.update(special_dct) 

1732 

1733 # dict params 

1734 dict_dct = { 

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

1736 } 

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

1738 ldau_dict = set_ldau( 

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

1740 luj_params=dict_dct['ldau_luj'], 

1741 symbol_count=self.symbol_count) 

1742 dict_dct.update(ldau_dict) 

1743 del dict_dct['ldau_luj'] 

1744 incar_params.update(dict_dct) 

1745 

1746 # set magmom based on input or initial atoms object 

1747 spinpol, magmom_dct = set_magmom( 

1748 atoms=atoms, 

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

1750 spinpol=self.spinpol, 

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

1752 sorting=self.sort, 

1753 ) 

1754 self.spinpol = spinpol 

1755 incar_params.update(magmom_dct) 

1756 

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

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

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

1760 # reliably and easily identify such non-standard entries 

1761 

1762 cust_dict = { 

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

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

1765 if val is not None 

1766 } 

1767 incar_params.update(cust_dict) 

1768 

1769 write_incar(directory=directory, parameters=incar_params) 

1770 

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

1772 """Writes the KPOINTS file.""" 

1773 

1774 if atoms is None: 

1775 atoms = self.atoms 

1776 

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

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

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

1780 return 

1781 else: 

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

1783 "Please use None or a positive number." 

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

1785 if self.input_params['kpts'] is None: 

1786 return 

1787 

1788 kpointstring = format_kpoints( 

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

1790 atoms=atoms, 

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

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

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

1794 kpoints.write(kpointstring) 

1795 

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

1797 """Writes the POTCAR file.""" 

1798 

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

1800 for filename in self.ppp_list: 

1801 with open_potcar(filename=filename) as ppp_file: 

1802 for line in ppp_file: 

1803 potfile.write(line) 

1804 

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

1806 """Writes a sortings file. 

1807 

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

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

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

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

1812 

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

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

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

1816 

1817 # The below functions are used to restart a calculation 

1818 

1819 def read_incar(self, filename): 

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

1821 

1822 Typically named INCAR.""" 

1823 

1824 self.spinpol = False 

1825 with open(filename) as fd: 

1826 lines = fd.readlines() 

1827 

1828 for line in lines: 

1829 try: 

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

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

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

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

1834 data = line.split() 

1835 # Skip empty and commented lines. 

1836 if len(data) == 0: 

1837 continue 

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

1839 continue 

1840 key = data[0].lower() 

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

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

1843 # Unconditionally add it, no type checking 

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

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

1846 # value should be '1 2 3' 

1847 

1848 # Split at first occurence of "=" 

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

1850 # First "#" denotes beginning of comment 

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

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

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

1854 elif key in float_keys: 

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

1856 elif key in exp_keys: 

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

1858 elif key in string_keys: 

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

1860 elif key in int_keys: 

1861 if key == 'ispin': 

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

1863 # out 

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

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

1866 self.spinpol = True 

1867 else: 

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

1869 elif key in bool_keys: 

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

1871 if val_char.startswith('t'): 

1872 self.bool_params[key] = True 

1873 elif val_char.startswith('f'): 

1874 self.bool_params[key] = False 

1875 else: 

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

1877 f'key "{key}"') 

1878 

1879 elif key in list_bool_keys: 

1880 self.list_bool_params[key] = [ 

1881 _from_vasp_bool(x) 

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

1883 ] 

1884 

1885 elif key in list_int_keys: 

1886 self.list_int_params[key] = [ 

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

1888 ] 

1889 

1890 elif key in list_float_keys: 

1891 if key == 'magmom': 

1892 lst = [] 

1893 i = 2 

1894 while i < len(data): 

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

1896 break 

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

1898 b = lst.pop() 

1899 i += 1 

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

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

1902 else: 

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

1904 i += 1 

1905 self.list_float_params['magmom'] = lst 

1906 lst = np.array(lst) 

1907 if self.atoms is not None: 

1908 self.atoms.set_initial_magnetic_moments( 

1909 lst[self.resort]) 

1910 else: 

1911 data = _args_without_comment(data) 

1912 self.list_float_params[key] = [ 

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

1914 ] 

1915 elif key in special_keys: 

1916 if key == 'lreal': 

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

1918 if val_char.startswith('t'): 

1919 self.bool_params[key] = True 

1920 elif val_char.startswith('f'): 

1921 self.bool_params[key] = False 

1922 else: 

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

1924 

1925 # non-registered keys 

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

1927 self.bool_params[key] = True 

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

1929 self.bool_params[key] = False 

1930 elif data[2].isdigit(): 

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

1932 else: 

1933 try: 

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

1935 except ValueError: 

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

1937 

1938 except KeyError as exc: 

1939 raise KeyError( 

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

1941 ) from exc 

1942 except IndexError as exc: 

1943 raise IndexError( 

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

1945 ) from exc 

1946 

1947 def read_kpoints(self, filename): 

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

1949 # If we used VASP builtin kspacing, 

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

1951 # Don't update kpts array 

1952 return 

1953 

1954 with open(filename) as fd: 

1955 lines = fd.readlines() 

1956 

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

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

1959 if ktype == 'g': 

1960 self.set(gamma=True) 

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

1962 elif ktype == 'a': 

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

1964 elif ktype == 'm': 

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

1966 else: 

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

1968 self.set(reciprocal=False) 

1969 else: 

1970 self.set(reciprocal=True) 

1971 kpts = np.array( 

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

1973 self.set(kpts=kpts) 

1974 

1975 def read_potcar(self, filename): 

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

1977 """ 

1978 

1979 # Search for key 'LEXCH' in POTCAR 

1980 xc_flag = None 

1981 with open(filename) as fd: 

1982 for line in fd: 

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

1984 if key == 'LEXCH': 

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

1986 break 

1987 

1988 if xc_flag is None: 

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

1990 

1991 # Values of parameter LEXCH and corresponding XC-functional 

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

1993 

1994 if xc_flag not in xc_dict.keys(): 

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

1996 ' LEXCH=%s' % xc_flag) 

1997 

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

1999 

2000 def todict(self): 

2001 """Returns a dictionary of all parameters 

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

2003 dict_list = [ 

2004 'float_params', 'exp_params', 'string_params', 'int_params', 

2005 'bool_params', 'list_bool_params', 'list_int_params', 

2006 'list_float_params', 'special_params', 'dict_params', 

2007 'input_params' 

2008 ] 

2009 dct = {} 

2010 for item in dict_list: 

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

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

2013 return dct 

2014 

2015 

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

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

2018 

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

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

2021 

2022 """ 

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

2024 if comment_locs == []: 

2025 return data 

2026 else: 

2027 return data[:min(comment_locs)] 

2028 

2029 

2030def _from_vasp_bool(x): 

2031 """Cast vasp boolean to Python bool 

2032 

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

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

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

2036 

2037 """ 

2038 assert isinstance(x, str) 

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

2040 return True 

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

2042 return False 

2043 else: 

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

2045 

2046 

2047def _to_vasp_bool(x): 

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

2049 

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

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

2052 

2053 """ 

2054 if isinstance(x, str): 

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

2056 x = True 

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

2058 x = False 

2059 else: 

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

2061 assert isinstance(x, bool) 

2062 if x: 

2063 return '.TRUE.' 

2064 else: 

2065 return '.FALSE.' 

2066 

2067 

2068def open_potcar(filename): 

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

2070 """ 

2071 import gzip 

2072 if filename.endswith('R'): 

2073 return open(filename) 

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

2075 return gzip.open(filename) 

2076 else: 

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

2078 

2079 

2080def read_potcar_numbers_of_electrons(file_obj): 

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

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

2083 nelect = [] 

2084 lines = file_obj.readlines() 

2085 for n, line in enumerate(lines): 

2086 if 'TITEL' in line: 

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

2088 valence = float( 

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

2090 nelect.append((symbol, valence)) 

2091 return nelect 

2092 

2093 

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

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

2096 

2097 Parameters: 

2098 atoms: Atoms object to be grouped 

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

2100 

2101 Returns: 

2102 Tuple of (symbols, symbolcount) 

2103 symbols: The unique symbols in the included list 

2104 symbolscount: Count of symbols in the included list 

2105 

2106 Example: 

2107 

2108 >>> from ase.build import bulk 

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

2110 >>> count_symbols(atoms) 

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

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

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

2114 """ 

2115 symbols = [] 

2116 symbolcount = {} 

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

2118 if m in exclude: 

2119 continue 

2120 if symbol not in symbols: 

2121 symbols.append(symbol) 

2122 symbolcount[symbol] = 1 

2123 else: 

2124 symbolcount[symbol] += 1 

2125 return symbols, symbolcount