Coverage for ase / calculators / vasp / create_input.py: 76.41%
619 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-30 08:22 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-30 08:22 +0000
1# fmt: off
3# Copyright (C) 2008 CSC - Scientific Computing Ltd.
4"""This module defines an ASE interface to VASP.
6Developed on the basis of modules by Jussi Enkovaara and John Kitchin.
7The pseudpotentials provided by VASP should be stored in a single directory
8that is defined by the environment variable VASP_PP_PATH. The VASP_PP_PATH
9should contain subdirectories of the form potpaw_LDA(.version) and
10potpaw_PBE(.version). The version of the pseudopotentials can be specified
11with the environment variable VASP_PP_VERSION or by the calculator input
12parameter 'pp_version'. If neither is set, the default is to use the
13unversioned directories to maintain backwards compatability.
15The user should also set the environmental flag $VASP_SCRIPT pointing
16to a python script looking something like::
18 import os
19 exitcode = os.system('vasp')
21Alternatively, user can set the environmental flag $VASP_COMMAND pointing
22to the command use the launch vasp e.g. 'vasp' or 'mpirun -n 16 vasp'
24https://www.vasp.at/
25"""
27import os
28import re
29import shutil
30import warnings
31from collections.abc import Sequence
32from os.path import join
33from typing import Any, TextIO
35import numpy as np
37import ase
38from ase import Atoms
39from ase.calculators.calculator import kpts2ndarray
40from ase.calculators.vasp.setups import get_default_setups
41from ase.config import cfg
42from ase.io.vasp_parsers.incar_writer import write_incar
44FLOAT_FORMAT = '5.6f'
45EXP_FORMAT = '5.2e'
48def check_ichain(ichain, ediffg, iopt):
49 ichain_dct = {}
50 if ichain > 0:
51 ichain_dct['ibrion'] = 3
52 ichain_dct['potim'] = 0.0
53 if iopt is None:
54 warnings.warn(
55 'WARNING: optimization is set to LFBGS (IOPT = 1)')
56 ichain_dct['iopt'] = 1
57 if ediffg is None or float(ediffg > 0.0):
58 raise RuntimeError('Please set EDIFFG < 0')
59 return ichain_dct
62def set_magmom(ispin, spinpol, atoms, magmom_input, sorting):
63 """Helps to set the magmom tag in the INCAR file with correct formatting"""
64 magmom_dct = {}
65 if magmom_input is not None:
66 if len(magmom_input) != len(atoms):
67 msg = ('Expected length of magmom tag to be'
68 ' {}, i.e. 1 value per atom, but got {}').format(
69 len(atoms), len(magmom_input))
70 raise ValueError(msg)
72 # Check if user remembered to specify ispin
73 # note: we do not overwrite ispin if ispin=1
74 if not ispin:
75 spinpol = True
76 # note that ispin is an int key, but for the INCAR it does not
77 # matter
78 magmom_dct['ispin'] = 2
79 magmom = np.array(magmom_input)
80 magmom = magmom[sorting]
81 elif (spinpol and atoms.get_initial_magnetic_moments().any()):
82 # We don't want to write magmoms if they are all 0.
83 # but we could still be doing a spinpol calculation
84 if not ispin:
85 magmom_dct['ispin'] = 2
86 # Write out initial magnetic moments
87 magmom = atoms.get_initial_magnetic_moments()[sorting]
88 # unpack magmom array if three components specified
89 if magmom.ndim > 1:
90 magmom = [item for sublist in magmom for item in sublist]
91 else:
92 return spinpol, {}
93 # Compactify the magmom list to symbol order
94 lst = [[1, magmom[0]]]
95 for n in range(1, len(magmom)):
96 if magmom[n] == magmom[n - 1]:
97 lst[-1][0] += 1
98 else:
99 lst.append([1, magmom[n]])
100 line = ' '.join(['{:d}*{:.4f}'.format(mom[0], mom[1])
101 for mom in lst])
102 magmom_dct['magmom'] = line
103 return spinpol, magmom_dct
106def set_ldau(ldau_param, luj_params, symbol_count):
107 """Helps to set the ldau tag in the INCAR file with correct formatting"""
108 ldau_dct = {}
109 if ldau_param is None:
110 ldau_dct['ldau'] = '.TRUE.'
111 llist = []
112 ulist = []
113 jlist = []
114 for symbol in symbol_count:
115 # default: No +U
116 luj = luj_params.get(
117 symbol[0],
118 {'L': -1, 'U': 0.0, 'J': 0.0}
119 )
120 llist.append(int(luj['L']))
121 ulist.append(f'{luj["U"]:{".3f"}}')
122 jlist.append(f'{luj["J"]:{".3f"}}')
123 ldau_dct['ldaul'] = llist
124 ldau_dct['ldauu'] = ulist
125 ldau_dct['ldauj'] = jlist
126 return ldau_dct
129def _calc_nelect_from_charge(
130 nelect: float | None,
131 charge: float | None,
132 nelect_from_ppp: float,
133) -> float | None:
134 """Determine nelect resulting from a given charge if charge != 0.0.
136 If nelect is additionally given explicitly, then we need to determine it
137 even for net charge of 0 to check for conflicts.
139 """
140 if charge is not None and charge != 0.0:
141 nelect_from_charge = nelect_from_ppp - charge
142 if nelect and nelect != nelect_from_charge:
143 raise ValueError(
144 'incompatible input parameters: '
145 f'nelect={nelect}, but charge={charge} '
146 f'(neutral nelect is {nelect_from_ppp})'
147 )
148 return nelect_from_charge
149 return nelect # NELECT explicitly given in INCAR (`None` if not given)
152def get_pp_setup(setup) -> tuple[dict, Sequence[int]]:
153 """
154 Get the pseudopotential mapping based on the "setpus" input.
156 Parameters
157 ----------
158 setup : [str, dict]
159 The setup to use for the calculation. This can be a string
160 shortcut, or a dict of atom identities and suffixes.
161 In the dict version it is also possible to select a base setup
162 e.g.: {'base': 'minimal', 'Ca': '_sv', 2: 'O_s'}
163 If the key is an integer, this means an atom index.
164 For the string version, 'minimal', 'recommended' and 'GW' are
165 available. The default is 'minimal
167 Returns
168 -------
169 setups : dict
170 The setup dictionary, with atom indices as keys and suffixes
171 as values.
172 special_setups : list
173 A list of atom indices that have a special setup.
174 """
175 special_setups = []
177 # Avoid mutating the module dictionary, so we use a copy instead
178 # Note, it is a nested dict, so a regular copy is not enough
179 setups_defaults = get_default_setups()
181 # Default to minimal basis
182 if setup is None:
183 setup = {'base': 'minimal'}
185 # String shortcuts are initialised to dict form
186 elif isinstance(setup, str):
187 if setup.lower() in setups_defaults.keys():
188 setup = {'base': setup}
190 # Dict form is then queried to add defaults from setups.py.
191 if 'base' in setup:
192 setups = setups_defaults[setup['base'].lower()]
193 else:
194 setups = {}
196 # Override defaults with user-defined setups
197 if setup is not None:
198 setups.update(setup)
200 for m in setups:
201 try:
202 special_setups.append(int(m))
203 except ValueError:
204 pass
205 return setups, special_setups
208def format_kpoints(kpts, atoms, reciprocal=False, gamma=False):
209 tokens = []
210 append = tokens.append
212 append('KPOINTS created by Atomic Simulation Environment\n')
214 if isinstance(kpts, dict):
215 kpts = kpts2ndarray(kpts, atoms=atoms)
216 reciprocal = True
218 shape = np.array(kpts).shape
220 # Wrap scalar in list if necessary
221 if shape == ():
222 kpts = [kpts]
223 shape = (1, )
225 if len(shape) == 1:
226 append('0\n')
227 if shape == (1, ):
228 append('Auto\n')
229 elif gamma:
230 append('Gamma\n')
231 else:
232 append('Monkhorst-Pack\n')
233 append(' '.join(f'{kpt:d}' for kpt in kpts))
234 append('\n0 0 0\n')
235 elif len(shape) == 2:
236 append('%i \n' % (len(kpts)))
237 if reciprocal:
238 append('Reciprocal\n')
239 else:
240 append('Cartesian\n')
241 for n in range(len(kpts)):
242 [append('%f ' % kpt) for kpt in kpts[n]]
243 if shape[1] == 4:
244 append('\n')
245 elif shape[1] == 3:
246 append('1.0 \n')
247 return ''.join(tokens)
250# Parameters that can be set in INCAR. The values which are None
251# are not written and default parameters of VASP are used for them.
253float_keys = [
254 'aexx', # Fraction of exact/DFT exchange
255 'aggac', # Fraction of gradient correction to correlation
256 'aggax', # Fraction of gradient correction to exchange
257 'aldac', # Fraction of LDA correlation energy
258 'amggac', # parameter that multiplies the meta-GGA correlation functional
259 'amggax', # parameter that multiplies the meta-GGA exchange functional
260 'amin', # minimal mixing parameter in Kerker's initial approximatio
261 'amix', # linear mixing parameter
262 'amix_mag', # linear mixing parameter for the magnetization density
263 'bmix', # tags for mixing
264 'bmix_mag', #
265 'cshift', # Complex shift for dielectric tensor calculation (LOPTICS)
266 'deper', # relative stopping criterion for optimization of eigenvalue
267 'ebreak', # absolute stopping criterion for optimization of eigenvalues
268 # (EDIFF/N-BANDS/4)
269 'efield', # applied electrostatic field
270 'emax', # energy-range for DOSCAR file
271 'emin', #
272 'enaug', # Density cutoff
273 'encut', # Planewave cutoff
274 'encutgw', # energy cutoff for response function
275 'encutfock', # FFT grid in the HF related routines
276 'hfscreen', # attribute to change from PBE0 to HSE
277 'kspacing', # determines the number of k-points if the KPOINTS
278 # file is not present. KSPACING is the smallest
279 # allowed spacing between k-points in units of
280 # $\AA$^{-1}$.
281 'potim', # time-step for ion-motion (fs)
282 'nelect', # total number of electrons
283 'param1', # Exchange parameter
284 'param2', # Exchange parameter
285 'pomass', # mass of ions in am
286 'pstress', # add this stress to the stress tensor, and energy E = V *
287 # pstress
288 'sigma', # broadening in eV
289 'smass', # Nose mass-parameter (am)
290 'spring', # spring constant for NEB
291 'time', # special control tag
292 'weimin', # maximum weight for a band to be considered empty
293 'zab_vdw', # vdW-DF parameter
294 'zval', # ionic valence
295 # The next keywords pertain to the VTST add-ons from Graeme Henkelman's
296 # group at UT Austin
297 'jacobian', # Weight of lattice to atomic motion
298 'ddr', # (DdR) dimer separation
299 'drotmax', # (DRotMax) number of rotation steps per translation step
300 'dfnmin', # (DFNMin) rotational force below which dimer is not rotated
301 'dfnmax', # (DFNMax) rotational force below which dimer rotation stops
302 'sltol', # convergence ratio for minimum eigenvalue
303 'sdr', # finite difference for setting up Lanczos matrix and step
304 # size when translating
305 'maxmove', # Max step for translation for IOPT > 0
306 'invcurv', # Initial curvature for LBFGS (IOPT = 1)
307 'timestep', # Dynamical timestep for IOPT = 3 and IOPT = 7
308 'sdalpha', # Ratio between force and step size for IOPT = 4
309 # The next keywords pertain to IOPT = 7 (i.e. FIRE)
310 'ftimemax', # Max time step
311 'ftimedec', # Factor to dec. dt
312 'ftimeinc', # Factor to inc. dt
313 'falpha', # Parameter for velocity damping
314 'falphadec', # Factor to dec. alpha
315 'clz', # electron count for core level shift
316 'vdw_radius', # Cutoff radius for Grimme's DFT-D2 and DFT-D3 and
317 # Tkatchenko and Scheffler's DFT-TS dispersion corrections
318 'vdw_scaling', # Global scaling parameter for Grimme's DFT-D2 dispersion
319 # correction
320 'vdw_d', # Global damping parameter for Grimme's DFT-D2 and Tkatchenko
321 # and Scheffler's DFT-TS dispersion corrections
322 'vdw_cnradius', # Cutoff radius for calculating coordination number in
323 # Grimme's DFT-D3 dispersion correction
324 'vdw_s6', # Damping parameter for Grimme's DFT-D2 and DFT-D3 and
325 # Tkatchenko and Scheffler's DFT-TS dispersion corrections
326 'vdw_s8', # Damping parameter for Grimme's DFT-D3 dispersion correction
327 'vdw_sr', # Scaling parameter for Grimme's DFT-D2 and DFT-D3 and
328 # Tkatchenko and Scheffler's DFT-TS dispersion correction
329 'vdw_a1', # Damping parameter for Grimme's DFT-D3 dispersion correction
330 'vdw_a2', # Damping parameter for Grimme's DFT-D3 dispersion correction
331 'eb_k', # solvent permitivity in Vaspsol
332 'tau', # surface tension parameter in Vaspsol
333 'langevin_gamma_l', # Friction for lattice degrees of freedom
334 'pmass', # Mass for latice degrees of freedom
335 'bparam', # B parameter for nonlocal VV10 vdW functional
336 'cparam', # C parameter for nonlocal VV10 vdW functional
337 'aldax', # Fraction of LDA exchange (for hybrid calculations)
338 'tebeg', #
339 'teend', # temperature during run
340 'andersen_prob', # Probability of collision in Andersen thermostat
341 'apaco', # Distance cutoff for pair correlation function calc.
342 'auger_ecblo', # Undocumented parameter for Auger calculations
343 'auger_edens', # Density of electrons in conduction band
344 'auger_hdens', # Density of holes in valence band
345 'auger_efermi', # Fixed Fermi level for Auger calculations
346 'auger_evbhi', # Upper bound for valence band maximum
347 'auger_ewidth', # Half-width of energy window function
348 'auger_occ_fac_eeh', # Undocumented parameter for Auger calculations
349 'auger_occ_fac_ehh', # Undocumented parameter for Auger calculations
350 'auger_temp', # Temperature for Auger calculation
351 'dq', # Finite difference displacement magnitude (NMR)
352 'avgap', # Average gap (Model GW)
353 'ch_sigma', # Broadening of the core electron absorption spectrum
354 'bpotim', # Undocumented Bond-Boost parameter (GH patches)
355 'qrr', # Undocumented Bond-Boost parameter (GH patches)
356 'prr', # Undocumented Bond-Boost parameter (GH patches)
357 'rcut', # Undocumented Bond-Boost parameter (GH patches)
358 'dvmax', # Undocumented Bond-Boost parameter (GH patches)
359 'bfgsinvcurv', # Initial curvature for BFGS (GH patches)
360 'damping', # Damping parameter for LBFGS (GH patches)
361 'efirst', # Energy of first NEB image (GH patches)
362 'elast', # Energy of final NEB image (GH patches)
363 'fmagval', # Force magnitude convergence criterion (GH patches)
364 'cmbj', # Modified Becke-Johnson MetaGGA c-parameter
365 'cmbja', # Modified Becke-Johnson MetaGGA alpha-parameter
366 'cmbjb', # Modified Becke-Johnson MetaGGA beta-parameter
367 'sigma_nc_k', # Width of ion gaussians (VASPsol)
368 'sigma_k', # Width of dielectric cavidty (VASPsol)
369 'nc_k', # Cavity turn-on density (VASPsol)
370 'lambda_d_k', # Debye screening length (VASPsol)
371 'ediffsol', # Tolerance for solvation convergence (VASPsol)
372 'soltemp', # Solvent temperature for isol 2 in Vaspsol++
373 'a_k', # Smoothing length for FFT for isol 2 in Vaspsol++
374 'r_cav', # Offset for solute surface area for isol 2 in Vaspsol++
375 'epsilon_inf', # Bulk optical dielectric for isol 2 in Vaspsol++
376 'n_mol', # Solvent density for isol 2 in Vaspsol++
377 'p_mol', # Solvent dipole moment for isol 2 in Vaspsol++
378 'r_solv', # Solvent radius for isol 2 in Vaspsol++
379 'r_diel', # Dielectric radius for isol 2 in Vaspsol++
380 'r_b', # Bound charge smearing length for isol 2 in Vaspsol++
381 'c_molar', # Electrolyte concentration for isol 2 in Vaspsol++
382 'zion', # Electrolyte ion valency for isol 2 in Vaspsol++
383 'd_ion', # Packing diameter of electrolyte ions for isol 2 in Vaspsol++
384 'r_ion', # Ionic radius of electrolyte ions for isol 2 in Vaspsol++
385 'efermi_ref', # Potential vs vacuum for isol 2 in Vaspsol++
386 'capacitance_init', # Initial guess for isol 2 in Vaspsol++
387 'deg_threshold', # Degeneracy threshold
388 'omegamin', # Minimum frequency for dense freq. grid
389 'omegamax', # Maximum frequency for dense freq. grid
390 'rtime', # Undocumented parameter
391 'wplasma', # Undocumented parameter
392 'wplasmai', # Undocumented parameter
393 'dfield', # Undocumented parameter
394 'omegatl', # Maximum frequency for coarse freq. grid
395 'encutgwsoft', # Soft energy cutoff for response kernel
396 'encutlf', # Undocumented parameter
397 'scissor', # Scissor correction for GW/BSE calcs
398 'dimer_dist', # Distance between dimer images
399 'step_size', # Step size for finite difference in dimer calculation
400 'step_max', # Maximum step size for dimer calculation
401 'minrot', # Minimum rotation allowed in dimer calculation
402 'dummy_mass', # Mass of dummy atom(s?)
403 'shaketol', # Tolerance for SHAKE algorithm
404 'shaketolsoft', # Soft tolerance for SHAKE algorithm
405 'shakesca', # Scaling of each step taken in SHAKE algorithm
406 'hills_stride', # Undocumented metadynamics parameter
407 'hills_h', # Height (in eV) of gaussian bias for metadynamics
408 'hills_w', # Width of gaussian bias for metadynamics
409 'hills_k', # Force constant coupling dummy&real for metadynamics
410 'hills_m', # Mass of dummy particle for use in metadynamics
411 'hills_temperature', # Temp. of dummy particle for metadynamics
412 'hills_andersen_prob', # Probability of thermostat coll. for metadynamics
413 'hills_sqq', # Nose-hoover particle mass for metadynamics
414 'dvvdelta0', # Undocumented parameter
415 'dvvvnorm0', # Undocumented parameter
416 'dvvminpotim', # Undocumented parameter
417 'dvvmaxpotim', # Undocumented parameter
418 'enchg', # Undocumented charge fitting parameter
419 'tau0', # Undocumented charge fitting parameter
420 'encut4o', # Cutoff energy for 4-center integrals (HF)
421 'param3', # Undocumented HF parameter
422 'model_eps0', # Undocumented HF parameter
423 'model_alpha', # Undocumented HF parameter
424 'qmaxfockae', # Undocumented HF parameter
425 'hfscreenc', # Range-separated screening length for correlations
426 'hfrcut', # Cutoff radius for HF potential kernel
427 'encutae', # Undocumented parameter for all-electron density calc.
428 'encutsubrotscf', # Undocumented subspace rotation SCF parameter
429 'enini', # Cutoff energy for wavefunctions (?)
430 'wc', # Undocumented mixing parameter
431 'enmax', # Cutoff energy for wavefunctions (?)
432 'scalee', # Undocumented parameter
433 'eref', # Reference energy
434 'epsilon', # Dielectric constant of bulk charged cells
435 'rcmix', # Mixing parameter for core density in rel. core calcs.
436 'esemicore', # Energetic lower bound for states considered "semicore"
437 'external_pressure', # Pressure for NPT calcs., equivalent to PSTRESS
438 'lj_radius', # Undocumented classical vdW parameter
439 'lj_epsilon', # Undocumented classical vdW parameter
440 'lj_sigma', # Undocumented classical vdW parameter
441 'mbd_beta', # TS MBD vdW correction damping parameter
442 'scsrad', # Cutoff radius for dipole-dipole interaction tensor in SCS
443 'hitoler', # Iterative Hirschfeld partitioning tolerance
444 'lambda', # "Spring constant" for magmom constraint calcs.
445 'kproj_threshold', # Threshold for k-point projection scheme
446 'maxpwamp', # Undocumented HF parameter
447 'vcutoff', # Undocumented parameter
448 'mdtemp', # Temperature for AIMD
449 'mdgamma', # Undocumented AIMD parameter
450 'mdalpha', # Undocumented AIMD parameter
451 'ofield_kappa', # Bias potential strength for interface pinning method
452 'ofield_q6_near', # Steinhardt-Nelson Q6 parameters for interface pinning
453 'ofield_q6_far', # Steinhardt-Nelson Q6 parameters for interface pinning
454 'ofield_a', # Target order parameter for interface pinning method
455 'pthreshold', # Don't print timings for routines faster than this value
456 'qltol', # Eigenvalue tolerance for Lanczos iteration (instanton)
457 'qdr', # Step size for building Lanczos matrix & CG (instanton)
458 'qmaxmove', # Max step size (instanton)
459 'qdt', # Timestep for quickmin minimization (instanton)
460 'qtpz', # Temperature (instanton)
461 'qftol', # Tolerance (instanton)
462 'nupdown', # fix spin moment to specified value
463]
465exp_keys = [
466 'ediff', # stopping-criterion for electronic upd.
467 'ediffg', # stopping-criterion for ionic upd.
468 'symprec', # precession in symmetry routines
469 # The next keywords pertain to the VTST add-ons from Graeme Henkelman's
470 # group at UT Austin
471 'fdstep', # Finite diference step for IOPT = 1 or 2
472]
474string_keys = [
475 'algo', # algorithm: Normal (Davidson) | Fast | Very_Fast (RMM-DIIS)
476 'bandgap', # determines the verbosity for reporting the bandgap info
477 'bseprec', # precision of the time-evolution algorithm
478 'gga', # xc-type: PW PB LM or 91 (LDA if not set)
479 'metagga', #
480 'prec', # Precission of calculation (Low, Normal, Accurate)
481 'system', # name of System
482 'precfock', # FFT grid in the HF related routines
483 'radeq', # Which type of radial equations to use for rel. core calcs.
484 'localized_basis', # Basis to use in CRPA
485 'proutine', # Select profiling routine
486 'efermi', # Sets the FERMI level in VASP 6.4.0+
487]
489int_keys = [
490 'ialgo', # algorithm: use only 8 (CG) or 48 (RMM-DIIS)
491 'ibrion', # ionic relaxation: 0-MD 1-quasi-New 2-CG
492 'icharg', # charge: 0-WAVECAR 1-CHGCAR 2-atom 10-const
493 'idipol', # monopol/dipol and quadropole corrections
494 'images', # number of images for NEB calculation
495 'imix', # specifies density mixing
496 'iniwav', # initial electr wf. : 0-lowe 1-rand
497 'isif', # calculate stress and what to relax
498 'ismear', # part. occupancies: -5 Blochl -4-tet -1-fermi 0-gaus >0 MP
499 'isearch', # line-search algorithm for ALGO = All
500 'ispin', # spin-polarized calculation
501 'istart', # startjob: 0-new 1-cont 2-samecut
502 'isym', # symmetry: 0-nonsym 1-usesym 2-usePAWsym
503 'iwavpr', # prediction of wf.: 0-non 1-charg 2-wave 3-comb
504 'kpar', # k-point parallelization paramater
505 'ldauprint', # 0-silent, 1-occ. matrix written to OUTCAR, 2-1+pot. matrix
506 # written
507 'ldautype', # L(S)DA+U: 1-Liechtenstein 2-Dudarev 4-Liechtenstein(LDAU)
508 'lmaxmix', #
509 'lorbit', # create PROOUT
510 'maxmix', #
511 'ngx', # FFT mesh for wavefunctions, x
512 'ngxf', # FFT mesh for charges x
513 'ngy', # FFT mesh for wavefunctions, y
514 'ngyf', # FFT mesh for charges y
515 'ngz', # FFT mesh for wavefunctions, z
516 'ngzf', # FFT mesh for charges z
517 'nbands', # Number of bands
518 'nblk', # blocking for some BLAS calls (Sec. 6.5)
519 'nbmod', # specifies mode for partial charge calculation
520 'nelm', # nr. of electronic steps (default 60)
521 'nelmdl', # nr. of initial electronic steps
522 'nelmgw', # nr. of self-consistency cycles for GW
523 'nelmin',
524 'nfree', # number of steps per DOF when calculting Hessian using
525 # finite differences
526 'nkred', # define sub grid of q-points for HF with
527 # nkredx=nkredy=nkredz
528 'nkredx', # define sub grid of q-points in x direction for HF
529 'nkredy', # define sub grid of q-points in y direction for HF
530 'nkredz', # define sub grid of q-points in z direction for HF
531 'nomega', # number of frequency points
532 'nomegar', # number of frequency points on real axis
533 'npar', # parallelization over bands
534 'nsim', # evaluate NSIM bands simultaneously if using RMM-DIIS
535 'nsw', # number of steps for ionic upd.
536 'nwrite', # verbosity write-flag (how much is written)
537 'vdwgr', # extra keyword for Andris program
538 'vdwrn', # extra keyword for Andris program
539 'voskown', # use Vosko, Wilk, Nusair interpolation
540 # The next keywords pertain to the VTST add-ons from Graeme Henkelman's
541 # group at UT Austin
542 'ichain', # Flag for controlling which method is being used (0=NEB,
543 # 1=DynMat, 2=Dimer, 3=Lanczos) if ichain > 3, then both
544 # IBRION and POTIM are automatically set in the INCAR file
545 'iopt', # Controls which optimizer to use. for iopt > 0, ibrion = 3
546 # and potim = 0.0
547 'snl', # Maximum dimentionality of the Lanczos matrix
548 'lbfgsmem', # Steps saved for inverse Hessian for IOPT = 1 (LBFGS)
549 'fnmin', # Max iter. before adjusting dt and alpha for IOPT = 7 (FIRE)
550 'icorelevel', # core level shifts
551 'clnt', # species index
552 'cln', # main quantum number of excited core electron
553 'cll', # l quantum number of excited core electron
554 'ivdw', # Choose which dispersion correction method to use
555 'nbandsgw', # Number of bands for GW
556 'nbandso', # Number of occupied bands for electron-hole treatment
557 'nbandsv', # Number of virtual bands for electron-hole treatment
558 'ncore', # Number of cores per band, equal to number of cores divided
559 # by npar
560 'mdalgo', # Determines which MD method of Tomas Bucko to use
561 'nedos', # Number of grid points in DOS
562 'turbo', # Ewald, 0 = Normal, 1 = PME
563 'omegapar', # Number of groups for response function calc.
564 # (Possibly Depricated) Number of groups in real time for
565 # response function calc.
566 'taupar',
567 'ntaupar', # Number of groups in real time for response function calc.
568 'antires', # How to treat antiresonant part of response function
569 'magatom', # Index of atom at which to place magnetic field (NMR)
570 'jatom', # Index of atom at which magnetic moment is evaluated (NMR)
571 'ichibare', # chi_bare stencil size (NMR)
572 'nbas', # Undocumented Bond-Boost parameter (GH patches)
573 'rmds', # Undocumented Bond-Boost parameter (GH patches)
574 'ilbfgsmem', # Number of histories to store for LBFGS (GH patches)
575 'vcaimages', # Undocumented parameter (GH patches)
576 'ntemper', # Undocumented subspace diagonalization param. (GH patches)
577 'ncshmem', # Share memory between this many cores on each process
578 'lmaxtau', # Undocumented MetaGGA parameter (prob. max ang.mom. for tau)
579 'kinter', # Additional finer grid (?)
580 'ibse', # Type of BSE calculation
581 'nbseeig', # Number of BSE wfns to write
582 'naturalo', # Use NATURALO (?)
583 'nbandsexact', # Undocumented parameter
584 'nbandsgwlow', # Number of bands for which shifts are calculated
585 'nbandslf', # Number of bands included in local field effect calc.
586 'omegagrid', # Undocumented parameter
587 'telescope', # Undocumented parameter
588 'maxmem', # Amount of memory to allocate per core in MB
589 'nelmhf', # Number of iterations for HF part (GW)
590 'dim', # Undocumented parameter
591 'nkredlf', # Reduce k-points for local field effects
592 'nkredlfx', # Reduce k-points for local field effects in X
593 'nkredlfy', # Reduce k-points for local field effects in Y
594 'nkredlfz', # Reduce k-points for local field effects in Z
595 'lmaxmp2', # Undocumented parameter
596 'switch', # Undocumented dimer parameter
597 'findiff', # Use forward (1) or central (2) finite difference for dimer
598 'engine', # Undocumented dimer parameter
599 'restartcg', # Undocumented dimer parameter
600 'thermostat', # Deprecated parameter for selecting MD method (use MDALGO)
601 'scaling', # After how many steps velocities should be rescaled
602 'shakemaxiter', # Maximum # of iterations in SHAKE algorithm
603 'equi_regime', # Number of steps to equilibrate for
604 'hills_bin', # Update metadynamics bias after this many steps
605 'hills_maxstride', # Undocumented metadynamics parameter
606 'dvvehistory', # Undocumented parameter
607 'ipead', # Undocumented parameter
608 'ngaus', # Undocumented charge fitting parameter
609 'exxoep', # Undocumented HF parameter
610 'fourorbit', # Undocumented HF parameter
611 'model_gw', # Undocumented HF parameter
612 'hflmax', # Maximum L quantum number for HF calculation
613 'lmaxfock', # Maximum L quantum number for HF calc. (same as above)
614 'lmaxfockae', # Undocumented HF parameter
615 'nmaxfockae', # Undocumented HF parameter
616 'nblock_fock', # Undocumented HF parameter
617 'idiot', # Determines which warnings/errors to print
618 'nrmm', # Number of RMM-DIIS iterations
619 'mremove', # Undocumented mixing parameter
620 'inimix', # Undocumented mixing parameter
621 'mixpre', # Undocumented mixing parameter
622 'nelmall', # Undocumented parameter
623 'nblock', # How frequently to write data
624 'kblock', # How frequently to write data
625 'npaco', # Undocumented pair correlation function parameter
626 'lmaxpaw', # Max L quantum number for on-site charge expansion
627 'irestart', # Undocumented parameter
628 'nreboot', # Undocumented parameter
629 'nmin', # Undocumented parameter
630 'nlspline', # Undocumented parameter
631 'ispecial', # "Select undocumented and unsupported special features"
632 'rcrep', # Number of steps between printing relaxed core info
633 'rcndl', # Wait this many steps before updating core density
634 'rcstrd', # Relax core density after this many SCF steps
635 'vdw_idampf', # Select type of damping function for TS vdW
636 'i_constrained_m', # Select type of magmom. constraint to use
637 'igpar', # "G parallel" direction for Berry phase calculation
638 'nppstr', # Number of kpts in "igpar' direction for Berry phase calc.
639 'nbands_out', # Undocumented QP parameter
640 'kpts_out', # Undocumented QP parameter
641 'isp_out', # Undocumented QP parameter
642 'nomega_out', # Undocumented QP parameter
643 'maxiter_ft', # Max iterations for sloppy Remez algorithm
644 'nmaxalt', # Max sample points for alternant in Remez algorithms
645 'itmaxlsq', # Max iterations in LSQ search algorithm
646 'ndatalsq', # Number of sample points for LSQ search algorithm
647 'ncore_in_image1', # Undocumented parameter
648 'kimages', # Undocumented parameter
649 'ncores_per_band', # Undocumented parameter
650 'maxlie', # Max iterations in CRPA diagonalization routine
651 'ncrpalow', # Undocumented CRPA parameter
652 'ncrpahigh', # Undocumented CRPA parameter
653 'nwlow', # Undocumented parameter
654 'nwhigh', # Undocumented parameter
655 'nkopt', # Number of k-points to include in Optics calculation
656 'nkoffopt', # K-point "counter offset" for Optics
657 'nbvalopt', # Number of valence bands to write in OPTICS file
658 'nbconopt', # Number of conduction bands to write in OPTICS file
659 'ch_nedos', # Number dielectric function calculation grid points for XAS
660 'plevel', # No timings for routines with "level" higher than this
661 'qnl', # Lanczos matrix size (instanton)
662 'isol', # vaspsol++ flag 1 linear, 2 nonlinear
663]
665bool_keys = [
666 'addgrid', # finer grid for augmentation charge density
667 'kgamma', # The generated kpoint grid (from KSPACING) is either
668 # centred at the $\Gamma$
669 # point (e.g. includes the $\Gamma$ point)
670 # (KGAMMA=.TRUE.)
671 'laechg', # write AECCAR0/AECCAR1/AECCAR2
672 'lasph', # non-spherical contributions to XC energy (and pot for
673 # VASP.5.X)
674 'lasync', # overlap communcation with calculations
675 'lcharg', #
676 'lcorr', # Harris-correction to forces
677 'ldau', # L(S)DA+U
678 'ldiag', # algorithm: perform sub space rotation
679 'ldipol', # potential correction mode
680 'lelf', # create ELFCAR
681 'lepsilon', # enables to calculate and to print the BEC tensors
682 'lhfcalc', # switch to turn on Hartree Fock calculations
683 'loptics', # calculate the frequency dependent dielectric matrix
684 'lpard', # evaluate partial (band and/or k-point) decomposed charge
685 # density
686 'lplane', # parallelisation over the FFT grid
687 'lscalapack', # switch off scaLAPACK
688 'lscalu', # switch of LU decomposition
689 'lsepb', # write out partial charge of each band separately?
690 'lsepk', # write out partial charge of each k-point separately?
691 'lthomas', #
692 'luse_vdw', # Invoke vdW-DF implementation by Klimes et. al
693 'lvdw', # Invoke DFT-D2 method of Grimme
694 'lvhar', # write Hartree potential to LOCPOT (vasp 5.x)
695 'lvtot', # create WAVECAR/CHGCAR/LOCPOT
696 'lwave', #
697 # The next keywords pertain to the VTST add-ons from Graeme Henkelman's
698 # group at UT Austin
699 'lclimb', # Turn on CI-NEB
700 'ltangentold', # Old central difference tangent
701 'ldneb', # Turn on modified double nudging
702 'lnebcell', # Turn on SS-NEB
703 'lglobal', # Optmize NEB globally for LBFGS (IOPT = 1)
704 'llineopt', # Use force based line minimizer for translation (IOPT = 1)
705 'lbeefens', # Switch on print of BEE energy contributions in OUTCAR
706 'lbeefbas', # Switch off print of all BEEs in OUTCAR
707 'lcalcpol', # macroscopic polarization (vasp5.2). 'lcalceps'
708 'lcalceps', # Macroscopic dielectric properties and Born effective charge
709 # tensors (vasp 5.2)
710 'lvdw', # Turns on dispersion correction
711 'lvdw_ewald', # Turns on Ewald summation for Grimme's DFT-D2 and
712 # Tkatchenko and Scheffler's DFT-TS dispersion correction
713 'lspectral', # Use the spectral method to calculate independent particle
714 # polarizability
715 'lrpa', # Include local field effects on the Hartree level only
716 'lwannier90', # Switches on the interface between VASP and WANNIER90
717 'lsorbit', # Enable spin-orbit coupling
718 'lsol', # turn on solvation for Vaspsol
719 'lnldiel', # turn on nonlinear dielectric in Vaspsol++
720 'lnlion', # turn on nonlinear ionic in Vaspsol++
721 'lsol_scf', # turn on solvation in SCF cycle in Vaspsol++
722 'lautoscale', # automatically calculate inverse curvature for VTST LBFGS
723 'interactive', # Enables interactive calculation for VaspInteractive
724 'lauger', # Perform Auger calculation (Auger)
725 'lauger_eeh', # Calculate EEH processes (Auger)
726 'lauger_ehh', # Calculate EHH processes (Auger)
727 'lauger_collect', # Collect wfns before looping over k-points (Auger)
728 'lauger_dhdk', # Auto-determine E. window width from E. derivs. (Auger)
729 'lauger_jit', # Distribute wavefunctions for k1-k4 (Auger)
730 'orbitalmag', # Enable orbital magnetization (NMR)
731 'lchimag', # Use linear response for shielding tensor (NMR)
732 'lwrtcur', # Write response of current to mag. field to file (NMR)
733 'lnmr_sym_red', # Reduce symmetry for finite difference (NMR)
734 'lzora', # Use ZORA approximation in linear-response NMR (NMR)
735 'lbone', # Use B-component in AE one-center terms for LR NMR (NMR)
736 'lmagbloch', # Use Bloch summations to obtain orbital magnetization (NMR)
737 'lgauge', # Use gauge transformation for zero moment terms (NMR)
738 'lbfconst', # Use constant B-field with sawtooth vector potential (NMR)
739 'nucind', # Use nuclear independent calculation (NMR)
740 'lnicsall', # Use all grid points for 'nucind' calculation (NMR)
741 'llraug', # Use two-center corrections for induced B-field (NMR)
742 'lbbm', # Undocumented Bond-Boost parameter (GH patches)
743 'lnoncollinear', # Do non-collinear spin polarized calculation
744 'bfgsdfp', # Undocumented BFGS parameter (GH patches)
745 'linemin', # Use line minimization (GH patches)
746 'ldneborg', # Undocumented NEB parameter (GH patches)
747 'dseed', # Undocumented dimer parameter (GH patches)
748 'linteract', # Undocumented parameter (GH patches)
749 'lmpmd', # Undocumented parameter (GH patches)
750 'ltwodim', # Makes stress tensor two-dimensional (GH patches)
751 'fmagflag', # Use force magnitude as convergence criterion (GH patches)
752 'ltemper', # Use subspace diagonalization (?) (GH patches)
753 'qmflag', # Undocumented FIRE parameter (GH patches)
754 'lmixtau', # Undocumented MetaGGA parameter
755 'ljdftx', # Undocumented VASPsol parameter (VASPsol)
756 'lrhob', # Write the bound charge density (VASPsol)
757 'lrhoion', # Write the ionic charge density (VASPsol)
758 'lnabla', # Undocumented parameter
759 'linterfast', # Interpolate in K using linear response routines
760 'lvel', # Undocumented parameter
761 'lrpaforce', # Calculate RPA forces
762 'lhartree', # Use IP approx. in BSE (testing only)
763 'ladder', # Use ladder diagrams
764 'lfxc', # Use approximate ladder diagrams
765 'lrsrpa', # Undocumented parameter
766 'lsingles', # Calculate HF singles
767 'lfermigw', # Iterate Fermi level
768 'ltcte', # Undocumented parameter
769 'ltete', # Undocumented parameter
770 'ltriplet', # Undocumented parameter
771 'lfxceps', # Undocumented parameter
772 'lfxheg', # Undocumented parameter
773 'l2order', # Undocumented parameter
774 'lmp2lt', # Undocumented parameter
775 'lgwlf', # Undocumented parameter
776 'lusew', # Undocumented parameter
777 'selfenergy', # Undocumented parameter
778 'oddonlygw', # Avoid gamma point in response function calc.
779 'evenonlygw', # Avoid even points in response function calc.
780 'lspectralgw', # More accurate self-energy calculation
781 'ch_lspec', # Calculate matrix elements btw. core and conduction states
782 'fletcher_reeves', # Undocumented dimer parameter
783 'lidm_selective', # Undocumented dimer parameter
784 'lblueout', # Write output of blue-moon algorithm
785 'hills_variable_w', # Enable variable-width metadynamics bias
786 'dvvminus', # Undocumented parameter
787 'lpead', # Calculate cell-periodic orbital derivs. using finite diff.
788 'skip_edotp', # Skip updating elec. polarization during scf
789 'skip_scf', # Skip calculation w/ local field effects
790 'lchgfit', # Turn on charge fitting
791 'lgausrc', # Undocumented charge fitting parameter
792 'lstockholder', # Enable ISA charge fitting (?)
793 'lsymgrad', # Restore symmetry of gradient (HF)
794 'lhfone', # Calculate one-center terms (HF)
795 'lrscor', # Include long-range correlation (HF)
796 'lrhfcalc', # Include long-range HF (HF)
797 'lmodelhf', # Model HF calculation (HF)
798 'shiftred', # Undocumented HF parameter
799 'hfkident', # Undocumented HF parameter
800 'oddonly', # Undocumented HF parameter
801 'evenonly', # Undocumented HF parameter
802 'lfockaedft', # Undocumented HF parameter
803 'lsubrot', # Enable subspace rotation diagonalization
804 'mixfirst', # Mix before diagonalization
805 'lvcader', # Calculate derivs. w.r.t. VCA parameters
806 'lcompat', # Enable "full compatibility"
807 'lmusic', # "Joke" parameter
808 'ldownsample', # Downsample WAVECAR to fewer k-points
809 'lscaaware', # Disable ScaLAPACK for some things but not all
810 'lorbitalreal', # Undocumented parameter
811 'lmetagga', # Undocumented parameter
812 'lspiral', # Undocumented parameter
813 'lzeroz', # Undocumented parameter
814 'lmono', # Enable "monopole" corrections
815 'lrelcore', # Perform relaxed core calculation
816 'lmimicfc', # Mimic frozen-core calcs. for relaxed core calcs.
817 'lmatchrw', # Match PS partial waves at RWIGS? (otherwise PAW cutoff)
818 'ladaptelin', # Linearize core state energies to avoid divergences
819 'lonlysemicore', # Only linearize semi-core state energies
820 'gga_compat', # Enable backwards-compatible symmetrization of GGA derivs.
821 'lrelvol', # Undocumented classical vdW parameter
822 'lj_only', # Undocumented classical vdW parameter
823 'lvdwscs', # Include self-consistent screening in TS vdW correction
824 'lcfdm', # Use coupled fluctuating dipoles model for TS vdW
825 'lvdw_sametype', # Include interactions between atoms of the same type
826 'lrescaler0', # Rescale damping parameters in SCS vdW correction
827 'lscsgrad', # Calculate gradients for TS+SCS vdW correction energies
828 'lvdwexpansion', # Write 2-6 body contribs. to MBD vdW correction energy
829 'lvdw_relvolone', # Undocumented classical vdW parameter
830 'lberry', # Enable Berry-phase calculation
831 'lpade_fit', # Undocumented QP parameter
832 'lkproj', # Enable projection onto k-points
833 'l_wr_moments', # Undocumented parameter
834 'l_wr_density', # Undocumented parameter
835 'lkotani', # Undocumented parameter
836 'ldyson', # Undocumented parameter
837 'laddherm', # Undocumented parameter
838 'lcrpaplot', # Plot bands used in CRPA response func. calc.
839 'lplotdis', # Plot disentangled bands in CRPA response func. calc.
840 'ldisentangle', # Disentangle bands in CRPA
841 'lweighted', # "Weighted" CRPA approach
842 'luseorth_lcaos', # Use orthogonalized LCAOs in CRPA
843 'lfrpa', # Use full RPA in CRPA
844 'lregularize', # Regularize projectors in CRPA
845 'ldrude', # Include Drude term in CRPA
846 'ldmatrix', # Undocumented parameter
847 'lefg', # Calculate electric field gradient at atomic nuclei
848 'lhyperfine', # Enable Hyperfine calculation
849 'lwannier', # Enable Wannier interface
850 'localize', # Undocumented Wannier parameter
851 'lintpol_wpot', # Interpolate WPOT for Wannier
852 'lintpol_orb', # Interpolate orbitals for Wannier
853 'lintpol_kpath', # Interpolate bandstructure on given kpath for Wannier
854 'lintpol_kpath_orb', # Interpolate orbitals on given kpath for Wannier
855 'lread_eigenvalues', # Use Eigenvalues from EIGENVALUES.INT file
856 'lintpol_velocity', # Interpolate electron velocity for Wannier
857 'lintpol_conductivity', # Interpolate conductivity for Wannier
858 'lwannierinterpol', # Undocumented Wannier parameter
859 'wanproj', # Undocumented Wannier parameter
860 'lorbmom', # Undocumented LDA+U parameter
861 'lwannier90_run', # Undocumented WANNIER90 parameter
862 'lwrite_wanproj', # Write UWAN files for WANNIER90
863 'lwrite_unk', # Write UNK files for WANNIER90
864 'lwrite_mmn_amn', # Write MMN and AMN files for WANNIER90
865 'lread_amn', # Read AMN files instead of recomputing (WANNIER90)
866 'lrhfatm', # Undocumented HF parameter
867 'lvpot', # Calculate unscreened potential
868 'lwpot', # Calculate screened potential
869 'lwswq', # Undocumented parameter
870 'pflat', # Only print "flat" timings to OUTCAR
871 'qifcg', # Use CG instead of quickmin (instanton)
872 'qdo_ins', # Find instanton
873 'qdo_pre', # Calculate prefactor (instanton)
874 # The next keyword pertains to the periodic NBO code of JR Schmidt's group
875 # at UW-Madison (https://github.com/jrschmidt2/periodic-NBO)
876 'lnbo', # Enable NBO analysis
877]
879list_int_keys = [
880 'iband', # bands to calculate partial charge for
881 'kpuse', # k-point to calculate partial charge for
882 'ldaul', # DFT+U parameters, overruled by dict key 'ldau_luj'
883 'random_seed', # List of ints used to seed RNG for advanced MD routines
884 # (Bucko)
885 'auger_bmin_eeh', # 4 ints | Various undocumented parameters for Auger
886 'auger_bmax_eeh', # 4 ints | calculations
887 'auger_bmin_ehh', # 4 ints |
888 'auger_bmax_ehh', # 4 ints |
889 'balist', # nbas ints | Undocumented Bond-Boost parameter (GH patches)
890 'kpoint_bse', # 4 ints | Undocumented parameter
891 'nsubsys', # <=3 ints | Last atom # for each of up to 3 thermostats
892 'vdw_refstate', # ntyp ints | Undocumented classical vdW parameter
893 'vdw_mbd_size', # 3 ints | Supercell size for TS MBD vdW correction
894 'nbands_index', # nbands_out ints | Undocumented QP parameter
895 'kpts_index', # kpts_out ints | Undocumented QP parameter
896 'isp_index', # isp_out ints | Undocumented QP parameter
897 'nomega_index', # nomega_out ints | Undocumented QP parameter
898 'ntarget_states', # nbands ints | Undocumented CRPA parameter
899 'wanproj_i', # nions ints | Undocumented Wannier parameter
900 'wanproj_l', # ? ints | Undocumented Wannier parameter
901]
903list_bool_keys = [
904 'lattice_constraints', # 3 bools | Undocumented advanced MD parameter
905 'lrctype', # ntyp bools | Enable relaxed-core calc. for these atoms
906 'lvdw_onecell', # 3 bools | Enable periodicity in A, B, C vector for vdW
907]
909list_float_keys = [
910 'dipol', # center of cell for dipol
911 'eint', # energy range to calculate partial charge for
912 'ferwe', # Fixed band occupation (spin-paired)
913 'ferdo', # Fixed band occupation (spin-plarized)
914 'magmom', # initial magnetic moments
915 'ropt', # number of grid points for non-local proj in real space
916 'rwigs', # Wigner-Seitz radii
917 'ldauu', # ldau parameters, has potential to redundant w.r.t. dict
918 'ldauj', # key 'ldau_luj', but 'ldau_luj' can't be read direct from
919 # the INCAR (since it needs to know information about atomic
920 # species. In case of conflict 'ldau_luj' gets written out
921 # when a calculation is set up
922 'vdw_c6', # List of floats of C6 parameters (J nm^6 mol^-1) for each
923 # species (DFT-D2 and DFT-TS)
924 'vdw_c6au', # List of floats of C6 parameters (a.u.) for each species
925 # (DFT-TS)
926 'vdw_r0', # List of floats of R0 parameters (angstroms) for each
927 # species (DFT-D2 and DFT-TS)
928 'vdw_r0au', # List of floats of R0 parameters (a.u.) for each species
929 # (DFT-TS)
930 'vdw_alpha', # List of floats of free-atomic polarizabilities for each
931 # species (DFT-TS)
932 'langevin_gamma', # List of floats for langevin friction coefficients
933 'auger_emin_eeh', # 4 floats | Various undocumented parameters for Auger
934 'auger_emax_eeh', # 4 floats | calculations
935 'auger_emin_ehh', # 4 floats |
936 'auger_emax_ehh', # 4 floats |
937 'avecconst', # 3 floats | magnitude of magnetic moment (NMR)
938 'magdipol', # 3 floats | magnitude of magnetic dipole (NMR)
939 'bconst', # 3 floats | magnitude of constant magnetic field (NMR)
940 'magpos', # 3 floats | position for magnetic moment w/ 'nucind' (NMR)
941 'bext', # 3 floats | Undocumented (probably external magnetic field)
942 'core_c', # ntyp floats | pseudo-core charge magnitude (VASPsol)
943 'sigma_rc_k', # ntyp floats | width of pseudo-core gaussians (VASPsol)
944 'darwinr', # ntypd (?) floats | Undocumented parameter
945 'darwinv', # ntypd (?) floats | Undocumented parameter
946 'dummy_k', # ? floats | Force const. connecting dummy atoms to sys.
947 'dummy_r0', # ? floats | Minimum dist., ang., etc. for dummy atom DOFs
948 'dummy_positions', # 3 floats | Position of dummy atom(s?)
949 'psubsys', # <=3 floats | Coll. prob. for each of up to 3 thermostats
950 'tsubsys', # <=3 floats | Temp. for each of up to 3 thermostats
951 'increm', # ? floats | Undocumented advanced MD parameter
952 'value_min', # ? floats | Undocumented advanced MD parameter
953 'value_max', # ? floats | Undocumented advanced MD parameter
954 'hills_position', # ? floats | Dummy particle(s) pos. for metadynamics
955 'hills_velocity', # ? floats | Dummy particle(s) vel. for metadynamics
956 'spring_k', # ? floats | Spring constant for harmonic constraints
957 'spring_r0', # ? floats | Spring minima for harmonic constraints
958 'spring_v0', # ? floats | Initial velocity of harmonic constraints
959 'hills_wall_lower', # ? floats | Undocumented metadynamics parameter
960 'hills_wall_upper', # ? floats | Undocumented metadynamics parameter
961 'efield_pead', # 3 floats | homogeneous electric field for PEAD calc.
962 'zct', # ? floats | Undocumented charge fitting parameter
963 'rgaus', # ? floats | Undocumented charge fitting parameter
964 'hfalpha', # 10 floats | Undocumented HF parameter
965 'mcalpha', # 10 floats | Undocumented HF parameter
966 'saxis', # 3 floats | Coordinate for collinear spin calculations
967 'vca', # ? floats | Atom weight for VCA calculations
968 'stm', # 7 floats | "range for STM data"
969 'qspiral', # 3 floats | Undocumented parameter
970 'external_stress', # 6 floats | Target stress (adds w/ external_pressure)
971 'm_constr', # 3*nions floats | Local magmom assigned to each spin DOF
972 'quad_efg', # ntyp floats | Nuclear quadrupole moments
973 'ngyromag', # ntyp floats | Nuclear gyromagnetic ratios
974 'rcrhocut', # ntyp floats | Core density cutoff rad. for HF relcore calc
975 'ofield_k', # 3 floats | Undocumented parameter
976 'paripot', # ? floats | Undocumented parameter
977 'smearings', # ? floats | ismear,sigma smearing params to loop over
978 'wanproj_e', # 2 floats | Undocumented Wannier parameter
979]
981special_keys = [
982 'lreal', # non-local projectors in real space
983]
985dict_keys = [
986 'ldau_luj', # dictionary with L(S)DA+U parameters, e.g. {'Fe':{'L':2,
987 # 'U':4.0, 'J':0.9}, ...}
988]
990keys: list[str] = [
991 # 'NBLOCK' and KBLOCK inner block; outer block
992 # 'NPACO' and APACO distance and nr. of slots for P.C.
993 # 'WEIMIN, EBREAK, DEPER special control tags
994]
997class GenerateVaspInput:
998 # Parameters corresponding to 'xc' settings. This may be modified
999 # by the user in-between loading calculators.vasp submodule and
1000 # instantiating the calculator object with calculators.vasp.Vasp()
1001 xc_defaults = {
1002 'lda': {
1003 'pp': 'LDA'
1004 },
1005 # GGAs
1006 'blyp': { # https://www.vasp.at/forum/viewtopic.php?p=17234
1007 'pp': 'PBE',
1008 'gga': 'B5',
1009 'aldax': 1.00,
1010 'aggax': 1.00,
1011 'aggac': 1.00,
1012 'aldac': 0.00
1013 },
1014 'pbe': {
1015 'pp': 'PBE',
1016 'gga': 'PE'
1017 },
1018 'pw91': {
1019 'gga': '91'
1020 },
1021 'pbesol': {
1022 'gga': 'PS'
1023 },
1024 'revpbe': {
1025 'gga': 'RE'
1026 },
1027 'rpbe': {
1028 'gga': 'RP'
1029 },
1030 'am05': {
1031 'gga': 'AM'
1032 },
1033 # Meta-GGAs
1034 'tpss': {
1035 'metagga': 'TPSS'
1036 },
1037 'revtpss': {
1038 'metagga': 'RTPSS'
1039 },
1040 'm06l': {
1041 'metagga': 'M06L'
1042 },
1043 'ms0': {
1044 'metagga': 'MS0'
1045 },
1046 'ms1': {
1047 'metagga': 'MS1'
1048 },
1049 'ms2': {
1050 'metagga': 'MS2'
1051 },
1052 'scan': {
1053 'metagga': 'SCAN'
1054 },
1055 'rscan': {
1056 'metagga': 'RSCAN'
1057 },
1058 'r2scan': {
1059 'metagga': 'R2SCAN'
1060 },
1061 'mbj': {
1062 # Modified Becke-Johnson
1063 'metagga': 'MBJ',
1064 },
1065 'tb09': {
1066 # Alias for MBJ
1067 'metagga': 'MBJ',
1068 },
1069 # vdW-DFs
1070 'vdw-df': {
1071 'gga': 'RE',
1072 'luse_vdw': True,
1073 'aggac': 0.
1074 },
1075 'vdw-df-cx': {
1076 'gga': 'CX',
1077 'luse_vdw': True,
1078 'aggac': 0.
1079 },
1080 'vdw-df-cx0p': {
1081 'gga': 'CX',
1082 'luse_vdw': True,
1083 'aggac': 0.,
1084 'lhfcalc': True,
1085 'aexx': 0.2,
1086 'aggax': 0.8
1087 },
1088 'vdw-df3-opt1': {
1089 'gga': 'BO',
1090 'param1': 0.1122334456,
1091 'param2': 0.1234568,
1092 'aggac': 0.0,
1093 'luse_vdw': True,
1094 'ivdw_nl': 3,
1095 'alpha_vdw': 0.94950,
1096 'gamma_vdw': 1.12,
1097 },
1098 'vdw-df3-opt2': {
1099 'gga': 'MK',
1100 'param1': 0.1234568,
1101 'param2': 0.58,
1102 'aggac': 0.0,
1103 'luse_vdw': True,
1104 'ivdw_nl': 4,
1105 'zab_vdw': -1.8867,
1106 'alpha_vdw': 0.28248,
1107 'gamma_vdw': 1.29,
1108 },
1109 'rvv10': {
1110 'gga': 'ML',
1111 'luse_vdw': True,
1112 'ivdw_nl': 2,
1113 'bparam': 6.3,
1114 'cparam': 0.0093,
1115 },
1116 'scan+rvv10': {
1117 'metagga': 'SCAN',
1118 'luse_vdw': True,
1119 'bparam': 15.7,
1120 'cparam': 0.0093,
1121 },
1122 'pbe+rvv10l': {
1123 'gga': 'PE',
1124 'luse_vdw': True,
1125 'bparam': 10,
1126 'cparam': 0.0093,
1127 },
1128 'r2scan+rvv10': {
1129 'metagga': 'R2SCAN',
1130 'luse_vdw': True,
1131 'bparam': 11.95,
1132 'cparam': 0.0093,
1133 },
1134 'optpbe-vdw': {
1135 'gga': 'OR',
1136 'luse_vdw': True,
1137 'aggac': 0.0
1138 },
1139 'optb88-vdw': {
1140 'gga': 'BO',
1141 'luse_vdw': True,
1142 'aggac': 0.0,
1143 'param1': 1.1 / 6.0,
1144 'param2': 0.22
1145 },
1146 'optb86b-vdw': {
1147 'gga': 'MK',
1148 'luse_vdw': True,
1149 'aggac': 0.0,
1150 'param1': 0.1234,
1151 'param2': 1.0
1152 },
1153 'vdw-df2': {
1154 'gga': 'ML',
1155 'luse_vdw': True,
1156 'aggac': 0.0,
1157 'zab_vdw': -1.8867
1158 },
1159 'rev-vdw-df2': {
1160 'gga': 'MK',
1161 'luse_vdw': True,
1162 'param1': 0.1234,
1163 'param2': 0.711357,
1164 'zab_vdw': -1.8867,
1165 'aggac': 0.0
1166 },
1167 'beef-vdw': {
1168 'gga': 'BF',
1169 'luse_vdw': True,
1170 'zab_vdw': -1.8867
1171 },
1172 # Hartree-Fock and hybrids
1173 'hf': {
1174 'lhfcalc': True,
1175 'aexx': 1.0,
1176 'aldac': 0.0,
1177 'aggac': 0.0
1178 },
1179 'b3lyp': {
1180 'gga': 'B3',
1181 'lhfcalc': True,
1182 'aexx': 0.2,
1183 'aggax': 0.72,
1184 'aggac': 0.81,
1185 'aldac': 0.19
1186 },
1187 'pbe0': {
1188 'gga': 'PE',
1189 'lhfcalc': True
1190 },
1191 'hse03': {
1192 'gga': 'PE',
1193 'lhfcalc': True,
1194 'hfscreen': 0.3
1195 },
1196 'hse06': {
1197 'gga': 'PE',
1198 'lhfcalc': True,
1199 'hfscreen': 0.2
1200 },
1201 'hsesol': {
1202 'gga': 'PS',
1203 'lhfcalc': True,
1204 'hfscreen': 0.2
1205 },
1206 # MN-VFM functionals
1207 'sogga': {
1208 'gga': 'SA'
1209 },
1210 'sogga11': {
1211 'gga': 'S1'
1212 },
1213 'sogga11-x': {
1214 'gga': 'SX',
1215 'lhfcalc': True,
1216 'aexx': 0.401
1217 },
1218 'n12': {
1219 'gga': 'N2'
1220 },
1221 'n12-sx': {
1222 'gga': 'NX',
1223 'lhfcalc': True,
1224 'lhfscreen': 0.2
1225 },
1226 'mn12l': {
1227 'metagga': 'MN12L'
1228 },
1229 'gam': {
1230 'gga': 'GA'
1231 },
1232 'mn15l': {
1233 'metagga': 'MN15L'
1234 },
1235 'hle17': {
1236 'metagga': 'HLE17'
1237 },
1238 'revm06l': {
1239 'metagga': 'revM06L'
1240 },
1241 'm06sx': {
1242 'metagga': 'M06SX',
1243 'lhfcalc': True,
1244 'hfscreen': 0.189,
1245 'aexx': 0.335
1246 }
1247 }
1249 # environment variable for PP paths
1250 VASP_PP_PATH = 'VASP_PP_PATH'
1251 VASP_PP_VERSION = 'VASP_PP_VERSION'
1253 def __init__(self, restart=None):
1254 self.float_params = {}
1255 self.exp_params = {}
1256 self.string_params = {}
1257 self.int_params = {}
1258 self.bool_params = {}
1259 self.list_bool_params = {}
1260 self.list_int_params = {}
1261 self.list_float_params = {}
1262 self.special_params = {}
1263 self.dict_params = {}
1264 self.atoms = None
1265 for key in float_keys:
1266 self.float_params[key] = None
1267 for key in exp_keys:
1268 self.exp_params[key] = None
1269 for key in string_keys:
1270 self.string_params[key] = None
1271 for key in int_keys:
1272 self.int_params[key] = None
1273 for key in bool_keys:
1274 self.bool_params[key] = None
1275 for key in list_bool_keys:
1276 self.list_bool_params[key] = None
1277 for key in list_int_keys:
1278 self.list_int_params[key] = None
1279 for key in list_float_keys:
1280 self.list_float_params[key] = None
1281 for key in special_keys:
1282 self.special_params[key] = None
1283 for key in dict_keys:
1284 self.dict_params[key] = None
1286 # Initialize internal dictionary of input parameters which are
1287 # not regular VASP keys
1288 self.input_params = {
1289 'xc': None, # Exchange-correlation recipe (e.g. 'B3LYP')
1290 'pp': None, # Pseudopotential file (e.g. 'PW91')
1291 'pp_version': None, # pseudopotential version (e.g. '52', '64')
1292 'setups': None, # Special setups (e.g pv, sv, ...)
1293 'txt': '-', # Where to send information
1294 'kpts': (1, 1, 1), # k-points
1295 # Option to use gamma-sampling instead of Monkhorst-Pack:
1296 'gamma': False,
1297 # number of points between points in band structures:
1298 'kpts_nintersections': None,
1299 # Option to write explicit k-points in units
1300 # of reciprocal lattice vectors:
1301 'reciprocal': False,
1302 # Switch to disable writing constraints to POSCAR
1303 'ignore_constraints': False,
1304 # Net charge for the whole system; determines nelect if not 0
1305 'charge': None,
1306 # Deprecated older parameter which works just like "charge" but
1307 # with the sign flipped
1308 'net_charge': None,
1309 # Custom key-value pairs, written to INCAR with *no* type checking
1310 'custom': {},
1311 }
1313 def set_xc_params(self, xc):
1314 """Set parameters corresponding to XC functional"""
1315 xc = xc.lower()
1316 if xc is None:
1317 pass
1318 elif xc not in self.xc_defaults:
1319 xc_allowed = ', '.join(self.xc_defaults.keys())
1320 raise ValueError('{} is not supported for xc! Supported xc values'
1321 'are: {}'.format(xc, xc_allowed))
1322 else:
1323 # XC defaults to PBE pseudopotentials
1324 if 'pp' not in self.xc_defaults[xc]:
1325 self.set(pp='PBE')
1326 self.set(**self.xc_defaults[xc])
1328 def set(self, **kwargs):
1330 if (('ldauu' in kwargs) and ('ldaul' in kwargs) and ('ldauj' in kwargs)
1331 and ('ldau_luj' in kwargs)):
1332 raise NotImplementedError(
1333 'You can either specify ldaul, ldauu, and ldauj OR '
1334 'ldau_luj. ldau_luj is not a VASP keyword. It is a '
1335 'dictionary that specifies L, U and J for each '
1336 'chemical species in the atoms object. '
1337 'For example for a water molecule:'
1338 '''ldau_luj={'H':{'L':2, 'U':4.0, 'J':0.9},
1339 'O':{'L':2, 'U':4.0, 'J':0.9}}''')
1341 if 'xc' in kwargs:
1342 self.set_xc_params(kwargs['xc'])
1343 for key, value in kwargs.items():
1344 if key in self.float_params:
1345 self.float_params[key] = value
1346 elif key in self.exp_params:
1347 self.exp_params[key] = value
1348 elif key in self.string_params:
1349 self.string_params[key] = value
1350 elif key in self.int_params:
1351 self.int_params[key] = value
1352 elif key in self.bool_params:
1353 self.bool_params[key] = value
1354 elif key in self.list_bool_params:
1355 self.list_bool_params[key] = value
1356 elif key in self.list_int_params:
1357 self.list_int_params[key] = value
1358 elif key in self.list_float_params:
1359 self.list_float_params[key] = value
1360 elif key in self.special_params:
1361 self.special_params[key] = value
1362 elif key in self.dict_params:
1363 self.dict_params[key] = value
1364 elif key in self.input_params:
1365 self.input_params[key] = value
1366 elif isinstance(value, str):
1367 self.string_params[key] = value
1368 # `bool` is a subclass of `int` and should be checked earlier.
1369 # https://docs.python.org/3/c-api/bool.html
1370 elif isinstance(value, bool):
1371 self.bool_params[key] = value
1372 elif isinstance(value, int):
1373 self.int_params[key] = value
1374 elif isinstance(value, float):
1375 self.float_params[key] = value
1376 elif isinstance(value, list):
1377 if len(value) == 0:
1378 msg = f'empty list is given for {key}'
1379 raise ValueError(msg)
1380 if isinstance(value[0], bool):
1381 self.list_bool_params[key] = value
1382 elif isinstance(value[0], int):
1383 self.list_int_params[key] = value
1384 elif isinstance(value[0], float):
1385 self.list_float_params[key] = value
1386 else:
1387 msg = f'cannot handle type of value for {key} = {value!r}'
1388 raise TypeError(msg)
1389 else:
1390 msg = f'cannot handle type of value for {key} = {value!r}'
1391 raise TypeError(msg)
1393 def check_xc(self):
1394 """Make sure the calculator has functional & pseudopotentials set up
1396 If no XC combination, GGA functional or POTCAR type is specified,
1397 default to PW91. Otherwise, try to guess the desired pseudopotentials.
1398 """
1400 p = self.input_params
1402 # There is no way to correctly guess the desired
1403 # set of pseudopotentials without 'pp' being set.
1404 # Usually, 'pp' will be set by 'xc'.
1405 if 'pp' not in p or p['pp'] is None:
1406 if self.string_params['gga'] is None:
1407 p.update({'pp': 'lda'})
1408 elif self.string_params['gga'] == 'PE':
1409 p.update({'pp': 'pbe'})
1410 else:
1411 raise NotImplementedError(
1412 "Unable to guess the desired set of pseudopotential"
1413 "(POTCAR) files. Please do one of the following: \n"
1414 "1. Use the 'xc' parameter to define your XC functional."
1415 "These 'recipes' determine the pseudopotential file as "
1416 "well as setting the INCAR parameters.\n"
1417 "2. Use the 'gga' settings None (default) or 'PE'; "
1418 "these correspond to LDA and PBE, respectively.\n"
1419 "3. Set the POTCAR explicitly with the 'pp' flag. The "
1420 "value should be the name of a folder on the VASP_PP_PATH"
1421 ", and the aliases 'LDA' and 'PBE' are also accepted.\n"
1422 )
1424 if (p['xc'] is not None and p['xc'].lower() == 'lda'
1425 and p['pp'].lower() != 'lda'):
1426 warnings.warn("XC is set to LDA, but PP is set to "
1427 "{0}. \nThis calculation is using the {0} "
1428 "POTCAR set. \n Please check that this is "
1429 "really what you intended!"
1430 "\n".format(p['pp'].upper()))
1432 def _make_sort(
1433 self, atoms: ase.Atoms, special_setups: Sequence[int] = ()
1434 ) -> tuple[list[int], list[int]]:
1435 symbols, _ = count_symbols(atoms, exclude=special_setups)
1437 # Create sorting list
1438 srt = [] # type: list[int]
1439 srt.extend(special_setups)
1441 for symbol in symbols:
1442 for m, atom in enumerate(atoms):
1443 if m in special_setups:
1444 continue
1445 if atom.symbol == symbol:
1446 srt.append(m)
1447 # Create the resorting list
1448 resrt = list(range(len(srt)))
1449 for n in range(len(resrt)):
1450 resrt[srt[n]] = n
1451 return srt, resrt
1453 def _set_spinpol(self, atoms):
1454 if self.int_params['ispin'] is None:
1455 self.spinpol = atoms.get_initial_magnetic_moments().any()
1456 else:
1457 # VASP runs non-spin-polarized calculations when `ispin=1`,
1458 # regardless if `magmom` is specified or not.
1459 self.spinpol = (self.int_params['ispin'] == 2)
1461 def _build_pp_list(self,
1462 atoms,
1463 setups=None,
1464 special_setups: Sequence[int] = ()):
1465 """Build the pseudopotential lists"""
1467 p = self.input_params
1469 if p['pp_version'] is not None:
1470 pp_version = p['pp_version']
1471 elif self.VASP_PP_VERSION in cfg:
1472 pp_version = cfg[self.VASP_PP_VERSION]
1473 else:
1474 pp_version = ''
1476 if setups is None:
1477 setups, special_setups = get_pp_setup(p['setups'])
1479 symbols, _ = count_symbols(atoms, exclude=special_setups)
1481 # Potpaw folders may be identified by an alias or full name
1482 for pp_alias, pp_folder in (('lda', f'potpaw_LDA.{pp_version}'
1483 if pp_version else 'potpaw'),
1484 ('pbe', f'potpaw_PBE.{pp_version}'
1485 if pp_version else 'potpaw_PBE')):
1486 if p['pp'].lower() == pp_alias:
1487 break
1488 else:
1489 pp_folder = p['pp']
1491 if self.VASP_PP_PATH in cfg:
1492 pppath = cfg[self.VASP_PP_PATH]
1493 if not os.path.exists(pppath):
1494 raise RuntimeError(f"VASP_PP_PATH does not exist: {pppath}")
1495 else:
1496 pppath = None
1497 ppp_list = []
1498 # Setting the pseudopotentials, first special setups and
1499 # then according to symbols
1500 for m in special_setups:
1501 if m in setups:
1502 special_setup_index = m
1503 elif str(m) in setups:
1504 special_setup_index = str(m) # type: ignore[assignment]
1505 else:
1506 raise Exception("Having trouble with special setup index {}."
1507 " Please use an int.".format(m))
1508 potcar = join(pp_folder, setups[special_setup_index], 'POTCAR')
1509 potcar_path = join(pppath, potcar) if pppath is not None else potcar
1511 if os.path.exists(potcar_path):
1512 ppp_list.append(potcar_path)
1513 elif os.path.exists(potcar_path + '.Z'):
1514 ppp_list.append(potcar_path + '.Z')
1515 else:
1516 msg = """Looking for {}.
1517 No pseudopotential for symbol{} with setup {} """.format(
1518 potcar_path, atoms.symbols[m], setups[special_setup_index])
1519 raise RuntimeError(msg)
1521 for symbol in symbols:
1522 try:
1523 potcar = join(pp_folder, symbol + setups[symbol], 'POTCAR')
1524 except (TypeError, KeyError):
1525 potcar = join(pp_folder, symbol, 'POTCAR')
1527 potcar_path = join(pppath, potcar) if pppath is not None else potcar
1529 if os.path.exists(potcar_path):
1530 ppp_list.append(potcar_path)
1531 elif os.path.exists(potcar_path + '.Z'):
1532 ppp_list.append(potcar_path + '.Z')
1533 else:
1534 msg = ("""Looking for {}
1535 The pseudopotentials are expected to be in:
1536 LDA: $VASP_PP_PATH/potpaw_LDA(.52|.54|.64)
1537 or $VASP_PP_PATH/potpaw
1538 PBE: $VASP_PP_PATH/potpaw_PBE(.52|.54|.64)
1540 No pseudopotential for {}!""".format(potcar_path, symbol
1541 ))
1542 raise RuntimeError(msg)
1543 return ppp_list
1545 def initialize(self, atoms: Atoms) -> None:
1546 """Initialize a VASP calculation
1548 Constructs the POTCAR file (does not actually write it).
1549 User should specify the PATH
1550 to the pseudopotentials in VASP_PP_PATH environment variable
1552 The pseudopotentials are expected to be in:
1553 LDA: $VASP_PP_PATH/potpaw_LDA(.52|.54|.64) or $VASP_PP_PATH/potpaw
1554 PBE: $VASP_PP_PATH/potpaw_PBE(.52|.54|.64)
1556 if your pseudopotentials are somewhere else, or named
1557 differently you may make symlinks at the paths above that
1558 point to the right place. Alternatively, you may pass the full
1559 name of a folder on the VASP_PP_PATH to the 'pp' parameter.
1560 """
1562 self.check_xc()
1563 self.atoms = atoms
1564 self.all_symbols = atoms.get_chemical_symbols()
1565 self.natoms = len(atoms)
1567 self._set_spinpol(atoms)
1569 setups, special_setups = get_pp_setup(self.input_params['setups'])
1571 # Determine the number of atoms of each atomic species
1572 # sorted after atomic species
1573 symbols, symbolcount = count_symbols(atoms, exclude=special_setups)
1574 self.sort, self.resort = self._make_sort(atoms,
1575 special_setups=special_setups)
1577 self.atoms_sorted = atoms[self.sort]
1579 # Check if the necessary POTCAR files exists and
1580 # create a list of their paths.
1581 atomtypes = atoms.get_chemical_symbols()
1582 self.symbol_count: list[tuple[str, int]] = []
1583 for m in special_setups:
1584 self.symbol_count.append((atomtypes[m], 1))
1585 for s in symbols:
1586 self.symbol_count.append((s, symbolcount[s]))
1588 # create pseudopotential list
1589 self.ppp_list = self._build_pp_list(
1590 atoms,
1591 setups=setups,
1592 special_setups=special_setups,
1593 )
1595 self.converged = None
1596 self.setups_changed = None
1598 def default_nelect_from_ppp(self) -> float:
1599 """ Get default number of electrons from ppp_list and symbol_count
1601 "Default" here means that the resulting cell would be neutral.
1602 """
1603 symbol_valences: list[tuple[str, float]] = []
1604 for filename in self.ppp_list:
1605 with open_potcar(filename=filename) as ppp_file:
1606 r = read_potcar_numbers_of_electrons(ppp_file)
1607 symbol_valences.extend(r)
1608 assert len(self.symbol_count) == len(symbol_valences)
1609 default_nelect = 0.0
1610 for ((symbol1, count),
1611 (symbol2, valence)) in zip(self.symbol_count, symbol_valences):
1612 assert symbol1 == symbol2
1613 default_nelect += count * valence
1614 return default_nelect
1616 def write_input(self, atoms, directory='./'):
1617 from ase.io.vasp import write_vasp
1618 write_vasp(join(directory, 'POSCAR'),
1619 self.atoms_sorted,
1620 symbol_count=self.symbol_count,
1621 ignore_constraints=self.input_params['ignore_constraints'])
1622 self.write_incar(atoms, directory=directory)
1623 self.write_potcar(directory=directory)
1624 self.write_kpoints(atoms=atoms, directory=directory)
1625 self.write_sort_file(directory=directory)
1626 self.copy_vdw_kernel(directory=directory)
1628 def copy_vdw_kernel(self, directory='./'):
1629 """Method to copy the vdw_kernel.bindat file.
1630 Set ASE_VASP_VDW environment variable to the vdw_kernel.bindat
1631 folder location. Checks if LUSE_VDW is enabled, and if no location
1632 for the vdW kernel is specified, a warning is issued."""
1634 vdw_env = 'ASE_VASP_VDW'
1635 kernel = 'vdw_kernel.bindat'
1636 dst = os.path.join(directory, kernel)
1638 # No need to copy the file again
1639 if os.path.isfile(dst):
1640 return
1642 if self.bool_params['luse_vdw']:
1643 src = None
1644 if vdw_env in cfg:
1645 src = os.path.join(cfg[vdw_env], kernel)
1647 if not src or not os.path.isfile(src):
1648 warnings.warn(
1649 ('vdW has been enabled, however no'
1650 ' location for the {} file'
1651 ' has been specified.'
1652 ' Set {} environment variable to'
1653 ' copy the vdW kernel.').format(kernel, vdw_env))
1654 else:
1655 shutil.copyfile(src, dst)
1657 def clean(self):
1658 """Method which cleans up after a calculation.
1660 The default files generated by Vasp will be deleted IF this
1661 method is called.
1663 """
1664 files = [
1665 'CHG', 'CHGCAR', 'POSCAR', 'INCAR', 'CONTCAR', 'DOSCAR',
1666 'EIGENVAL', 'IBZKPT', 'KPOINTS', 'OSZICAR', 'OUTCAR', 'PCDAT',
1667 'POTCAR', 'vasprun.xml', 'WAVECAR', 'XDATCAR', 'PROCAR',
1668 'ase-sort.dat', 'LOCPOT', 'AECCAR0', 'AECCAR1', 'AECCAR2'
1669 ]
1670 for f in files:
1671 try:
1672 os.remove(f)
1673 except OSError:
1674 pass
1676 def write_incar(self, atoms, directory='./', **kwargs):
1677 """Writes the INCAR file."""
1678 incar_params = {}
1680 # float params
1681 float_dct = {
1682 key: f'{val:{FLOAT_FORMAT}}'
1683 for key, val in self.float_params.items()
1684 if val is not None
1685 }
1687 if 'charge' in self.input_params and self.input_params[
1688 'charge'] is not None:
1689 nelect_val = _calc_nelect_from_charge(
1690 self.float_params['nelect'],
1691 self.input_params['charge'],
1692 self.default_nelect_from_ppp())
1693 if nelect_val:
1694 float_dct['nelect'] = f'{nelect_val:{FLOAT_FORMAT}}'
1695 incar_params.update(float_dct)
1697 # exp params
1698 exp_dct = {
1699 key: f'{val:{EXP_FORMAT}}'
1700 for key, val in self.exp_params.items()
1701 if val is not None
1702 }
1703 incar_params.update(exp_dct)
1705 # string_params
1706 string_dct = {
1707 key: val for key, val in self.string_params.items() if val is not
1708 None
1709 }
1710 incar_params.update(string_dct)
1712 # int params
1713 int_dct = {
1714 key: val for key, val in self.int_params.items() if val is not None
1715 }
1716 if 'ichain' in int_dct.keys():
1717 ichain_dict = check_ichain(
1718 ichain=int_dct['ichain'],
1719 ediffg=self.exp_params.get('ediffg', None),
1720 iopt=int_dct.get('iopt', None),
1721 )
1722 int_dct.update(ichain_dict)
1723 incar_params.update(int_dct)
1725 # list_bool_params
1726 bool_dct = {
1727 key: val
1728 for key, val in self.list_bool_params.items()
1729 if val is not None
1730 }
1731 for key, val in bool_dct.items():
1732 bool_dct[key] = [_to_vasp_bool(x) for x in val]
1733 incar_params.update(bool_dct)
1735 # list_int_params
1736 int_dct = {
1737 key: val
1738 for key, val in self.list_int_params.items()
1739 if val is not None
1740 }
1741 if 'ldaul' in int_dct.keys() and self.dict_params[
1742 'ldau_luj'] is not None:
1743 del int_dct['ldaul']
1744 incar_params.update(int_dct)
1746 # list_float_params
1747 float_dct = {
1748 key: val
1749 for key, val in self.list_float_params.items()
1750 if val is not None
1751 }
1752 if 'ldauu' in float_dct.keys() and self.dict_params[
1753 'ldau_luj'] is not None:
1754 del float_dct['ldauu']
1755 if 'ldauj' in float_dct.keys() and self.dict_params[
1756 'ldau_luj'] is not None:
1757 del float_dct['ldauj']
1758 incar_params.update(float_dct)
1760 # bool params
1761 bool_dct = {
1762 key: _to_vasp_bool(val)
1763 for key, val in self.bool_params.items()
1764 if val is not None
1765 }
1766 incar_params.update(bool_dct)
1768 # special params
1769 special_dct = {
1770 key: val for key, val in self.special_params.items() if val is not
1771 None
1772 }
1773 if 'lreal' in special_dct.keys():
1774 if isinstance(special_dct['lreal'], bool):
1775 special_dct['lreal'] = _to_vasp_bool(special_dct['lreal'])
1776 incar_params.update(special_dct)
1778 # dict params
1779 dict_dct = {
1780 key: val for key, val in self.dict_params.items() if val is not None
1781 }
1782 if 'ldau_luj' in dict_dct.keys():
1783 ldau_dict = set_ldau(
1784 ldau_param=self.bool_params['ldau'],
1785 luj_params=dict_dct['ldau_luj'],
1786 symbol_count=self.symbol_count)
1787 dict_dct.update(ldau_dict)
1788 del dict_dct['ldau_luj']
1789 incar_params.update(dict_dct)
1791 # set magmom based on input or initial atoms object
1792 spinpol, magmom_dct = set_magmom(
1793 atoms=atoms,
1794 ispin=self.int_params['ispin'],
1795 spinpol=self.spinpol,
1796 magmom_input=float_dct.get('magmom', None),
1797 sorting=self.sort,
1798 )
1799 self.spinpol = spinpol
1800 incar_params.update(magmom_dct)
1802 # Custom key-value pairs, which receive no formatting
1803 # Use the comment "# <Custom ASE key>" to denote such
1804 # a custom key-value pair, as we cannot otherwise
1805 # reliably and easily identify such non-standard entries
1807 cust_dict = {
1808 key: str(val) + ' # <Custom ASE key>'
1809 for key, val in self.input_params['custom'].items()
1810 if val is not None
1811 }
1812 incar_params.update(cust_dict)
1814 write_incar(directory=directory, parameters=incar_params)
1816 def write_kpoints(self, atoms=None, directory='./', **kwargs):
1817 """Writes the KPOINTS file."""
1819 if atoms is None:
1820 atoms = self.atoms
1822 # Don't write anything if KSPACING is being used
1823 if self.float_params['kspacing'] is not None:
1824 if self.float_params['kspacing'] > 0:
1825 return
1826 else:
1827 raise ValueError("KSPACING value {} is not allowable. "
1828 "Please use None or a positive number."
1829 "".format(self.float_params['kspacing']))
1830 if self.input_params['kpts'] is None:
1831 return
1833 kpointstring = format_kpoints(
1834 kpts=self.input_params['kpts'],
1835 atoms=atoms,
1836 reciprocal=self.input_params['reciprocal'],
1837 gamma=self.input_params['gamma'])
1838 with open(join(directory, 'KPOINTS'), 'w') as kpoints:
1839 kpoints.write(kpointstring)
1841 def write_potcar(self, suffix="", directory='./'):
1842 """Writes the POTCAR file."""
1844 with open(join(directory, 'POTCAR' + suffix), 'w') as potfile:
1845 for filename in self.ppp_list:
1846 with open_potcar(filename=filename) as ppp_file:
1847 for line in ppp_file:
1848 potfile.write(line)
1850 def write_sort_file(self, directory='./'):
1851 """Writes a sortings file.
1853 This file contains information about how the atoms are sorted in
1854 the first column and how they should be resorted in the second
1855 column. It is used for restart purposes to get sorting right
1856 when reading in an old calculation to ASE."""
1858 with open(join(directory, 'ase-sort.dat'), 'w') as fd:
1859 for n in range(len(self.sort)):
1860 fd.write('%5i %5i \n' % (self.sort[n], self.resort[n]))
1862 # The below functions are used to restart a calculation
1864 @staticmethod
1865 def set_if_none(collection: dict[str, Any], key: str, value: Any) -> None:
1866 collection[key] = value if collection.get(key) is None \
1867 else collection[key]
1869 def read_incar(self, filename):
1870 """Method that imports settings from INCAR file.
1872 Typically named INCAR."""
1874 self.spinpol = False
1875 with open(filename) as fd:
1876 lines = fd.readlines()
1878 for line in lines:
1879 try:
1880 # Make multiplication, comments, and parameters easier to spot
1881 line = line.replace("*", " * ")
1882 line = line.replace("=", " = ")
1883 line = line.replace("#", "# ")
1884 data = line.split()
1885 # Skip empty and commented lines.
1886 if len(data) == 0:
1887 continue
1888 elif data[0][0] in ['#', '!']:
1889 continue
1890 key = data[0].lower()
1891 if '<Custom ASE key>' in line:
1892 # This key was added with custom key-value pair formatting.
1893 # Unconditionally add it, no type checking
1894 # Get value between "=" and the comment, e.g.
1895 # key = 1 2 3 # <Custom ASE key>
1896 # value should be '1 2 3'
1898 # Split at first occurence of "="
1899 value = line.split('=', 1)[1]
1900 # First "#" denotes beginning of comment
1901 # Add everything before comment as a string to custom dict
1902 value = value.split('#', 1)[0].strip()
1903 self.set_if_none(self.inputs_params['custom'], key, value)
1904 elif key in float_keys:
1905 self.set_if_none(self.float_params, key, float(data[2]))
1906 elif key in exp_keys:
1907 self.set_if_none(self.exp_params, key, float(data[2]))
1908 elif key in string_keys:
1909 self.set_if_none(self.string_params, key, str(data[2]))
1910 elif key in int_keys:
1911 if key == 'ispin':
1912 # JRK added. not sure why we would want to leave ispin
1913 # out
1914 self.set_if_none(self.int_params, key, int(data[2]))
1915 if int(data[2]) == 2:
1916 self.spinpol = True
1917 else:
1918 self.set_if_none(self.int_params, key, int(data[2]))
1919 elif key in bool_keys:
1920 try:
1921 bool_val = _from_vasp_bool(data[2])
1922 except ValueError as exc:
1923 raise ValueError(f'Invalid value "{data[2]}" for bool '
1924 f'key "{key}"') from exc
1925 self.set_if_none(self.bool_params, key, bool_val)
1927 elif key in list_bool_keys:
1928 self.set_if_none(self.list_bool_params, key, [
1929 _from_vasp_bool(x)
1930 for x in _args_without_comment(data[2:])
1931 ])
1933 elif key in list_int_keys:
1934 self.set_if_none(self.list_int_params, key, [
1935 int(x) for x in _args_without_comment(data[2:])
1936 ])
1938 elif key in list_float_keys:
1939 if key == 'magmom':
1940 lst = []
1941 i = 2
1942 while i < len(data):
1943 if data[i] in ["#", "!"]:
1944 break
1945 if data[i] == "*":
1946 b = lst.pop()
1947 i += 1
1948 for _ in range(int(b)):
1949 lst.append(float(data[i]))
1950 else:
1951 lst.append(float(data[i]))
1952 i += 1
1953 self.set_if_none(self.list_float_params, 'magmom', lst)
1954 lst = np.array(lst)
1955 if self.atoms is not None:
1956 self.atoms.set_initial_magnetic_moments(
1957 lst[self.resort])
1958 else:
1959 data = _args_without_comment(data)
1960 self.set_if_none(self.list_float_params, key, [
1961 float(x) for x in data[2:]
1962 ])
1963 elif key in special_keys:
1964 if key == 'lreal':
1965 # can't use set_if_none since value might be in one of
1966 # two dicts
1967 if (self.bool_params.get(key) is not None or
1968 self.special_params.get(key) is not None):
1969 continue
1970 try:
1971 val = _from_vasp_bool(data[2])
1972 self.bool_params[key] = val
1973 except ValueError:
1974 self.special_params[key] = data[2]
1976 # non-registered keys
1977 elif data[2].lower() in {'t', 'true', '.true.'}:
1978 self.set_if_none(self.bool_params, key, True)
1979 elif data[2].lower() in {'f', 'false', '.false.'}:
1980 self.set_if_none(self.bool_params, key, False)
1981 elif data[2].isdigit():
1982 self.set_if_none(self.int_params, key, int(data[2]))
1983 else:
1984 try:
1985 self.set_if_none(self.float_params, key, float(data[2]))
1986 except ValueError:
1987 self.set_if_none(self.string_params, key, data[2])
1989 except KeyError as exc:
1990 raise KeyError(
1991 f'Keyword "{key}" in INCAR is not known by calculator.'
1992 ) from exc
1993 except IndexError as exc:
1994 raise IndexError(
1995 f'Value missing for keyword "{key}".'
1996 ) from exc
1998 def read_kpoints(self, filename):
1999 """Read kpoints file, typically named KPOINTS."""
2000 # If we used VASP builtin kspacing,
2001 if self.float_params['kspacing'] is not None:
2002 # Don't update kpts array
2003 return
2005 with open(filename) as fd:
2006 lines = fd.readlines()
2008 ktype = lines[2].split()[0].lower()[0]
2009 if ktype in ['g', 'm', 'a']:
2010 if ktype == 'g':
2011 self.set(gamma=True)
2012 kpts = np.array([int(lines[3].split()[i]) for i in range(3)])
2013 elif ktype == 'a':
2014 kpts = np.array([int(lines[3].split()[i]) for i in range(1)])
2015 elif ktype == 'm':
2016 kpts = np.array([int(lines[3].split()[i]) for i in range(3)])
2017 else:
2018 if ktype in ['c', 'k']:
2019 self.set(reciprocal=False)
2020 else:
2021 self.set(reciprocal=True)
2022 kpts = np.array(
2023 [list(map(float, line.split())) for line in lines[3:]])
2024 self.set(kpts=kpts)
2026 def read_potcar(self, filename):
2027 """ Read the pseudopotential XC functional from POTCAR file.
2028 """
2030 # Search for key 'LEXCH' in POTCAR
2031 xc_flag = None
2032 with open(filename) as fd:
2033 for line in fd:
2034 key = line.split()[0].upper()
2035 if key == 'LEXCH':
2036 xc_flag = line.split()[-1].upper()
2037 break
2039 if xc_flag is None:
2040 raise ValueError('LEXCH flag not found in POTCAR file.')
2042 # Values of parameter LEXCH and corresponding XC-functional
2043 xc_dict = {'PE': 'PBE', '91': 'PW91', 'CA': 'LDA'}
2045 if xc_flag not in xc_dict.keys():
2046 raise ValueError('Unknown xc-functional flag found in POTCAR,'
2047 ' LEXCH=%s' % xc_flag)
2049 self.input_params['pp'] = xc_dict[xc_flag]
2051 def todict(self):
2052 """Returns a dictionary of all parameters
2053 that can be used to construct a new calculator object"""
2054 dict_list = [
2055 'float_params', 'exp_params', 'string_params', 'int_params',
2056 'bool_params', 'list_bool_params', 'list_int_params',
2057 'list_float_params', 'special_params', 'dict_params',
2058 'input_params'
2059 ]
2060 dct = {}
2061 for item in dict_list:
2062 dct.update(getattr(self, item))
2063 dct = {key: value for key, value in dct.items() if value is not None}
2064 return dct
2067def _args_without_comment(data, marks=['!', '#']):
2068 """Check split arguments list for a comment, return data up to marker
2070 INCAR reader splits list arguments on spaces and leaves comment markers as
2071 individual items. This function returns only the data portion of the list.
2073 """
2074 comment_locs = [data.index(mark) for mark in marks if mark in data]
2075 if comment_locs == []:
2076 return data
2077 else:
2078 return data[:min(comment_locs)]
2081def _from_vasp_bool(x):
2082 """Cast vasp boolean to Python bool
2084 VASP files sometimes use T or F as shorthand for the preferred Boolean
2085 notation .TRUE. or .FALSE. As capitalisation is pretty inconsistent in
2086 practice, we allow all cases to be cast to a Python bool.
2088 """
2089 assert isinstance(x, str)
2090 if re.search(r'^\.?[tT]', x):
2091 return True
2092 elif re.search(r'^\.?[fF]', x):
2093 return False
2094 else:
2095 raise ValueError(f'Value "{x}" not recognized as bool')
2098def _to_vasp_bool(x):
2099 """Convert Python boolean to string for VASP input
2101 In case the value was modified to a string already, appropriate strings
2102 will also be accepted and cast to a standard .TRUE. / .FALSE. format.
2104 """
2105 if isinstance(x, str):
2106 if x.lower() in ('.true.', 't'):
2107 x = True
2108 elif x.lower() in ('.false.', 'f'):
2109 x = False
2110 else:
2111 raise ValueError('"%s" not recognised as VASP Boolean')
2112 assert isinstance(x, bool)
2113 if x:
2114 return '.TRUE.'
2115 else:
2116 return '.FALSE.'
2119def open_potcar(filename):
2120 """ Open POTCAR file with transparent decompression if it's an archive (.Z)
2121 """
2122 import gzip
2123 if filename.endswith('R'):
2124 return open(filename)
2125 elif filename.endswith('.Z'):
2126 return gzip.open(filename)
2127 else:
2128 raise ValueError(f'Invalid POTCAR filename: "{filename}"')
2131def read_potcar_numbers_of_electrons(fd: TextIO, /) -> list[tuple[str, float]]:
2132 """Read number of valence electrons for each atomtype from a POTCAR file.
2134 Returns
2135 -------
2136 list[tuple[str, float]]
2137 List of (atomic symbol, number of valence electrons).
2139 """
2140 nelect: list[tuple[str, float]] = []
2141 lines = fd.readlines()
2142 for n, line in enumerate(lines):
2143 if 'TITEL' in line:
2144 symbol = line.split('=')[1].split()[1].split('_')[0].strip()
2145 linep4 = lines[n + 4]
2146 zval = float(linep4.split(';')[1].split('=')[1].split()[0].strip())
2147 nelect.append((symbol, zval))
2148 return nelect
2151def count_symbols(atoms: Atoms, exclude=()) -> tuple[list[str], dict[str, int]]:
2152 """Count symbols in atoms object, excluding a set of indices
2154 Parameters
2155 ----------
2156 atoms: Atoms object to be grouped
2157 exclude: List of indices to be excluded from the counting
2159 Returns
2160 -------
2161 Tuple of (symbols, symbolcount)
2162 symbols: The unique symbols in the included list
2163 symbolscount: Count of symbols in the included list
2165 Example:
2167 >>> from ase.build import bulk
2168 >>> atoms = bulk('NaCl', crystalstructure='rocksalt', a=4.1, cubic=True)
2169 >>> count_symbols(atoms)
2170 (['Na', 'Cl'], {'Na': 4, 'Cl': 4})
2171 >>> count_symbols(atoms, exclude=(1, 2, 3))
2172 (['Na', 'Cl'], {'Na': 3, 'Cl': 2})
2173 """
2174 symbols: list[str] = []
2175 symbolcount: dict[str, int] = {}
2176 for m, symbol in enumerate(atoms.symbols):
2177 if m in exclude:
2178 continue
2179 if symbol not in symbols:
2180 symbols.append(symbol)
2181 symbolcount[symbol] = 1
2182 else:
2183 symbolcount[symbol] += 1
2184 return symbols, symbolcount