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
« prev ^ index » next coverage.py v7.5.3, created at 2025-06-18 01:20 +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
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.
11The user should also set the environmental flag $VASP_SCRIPT pointing
12to a python script looking something like::
14 import os
15 exitcode = os.system('vasp')
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'
20http://cms.mpi.univie.ac.at/vasp/
21"""
23import os
24import shutil
25import warnings
26from os.path import isfile, islink, join
27from typing import List, Sequence, Tuple
29import numpy as np
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
37FLOAT_FORMAT = '5.6f'
38EXP_FORMAT = '5.2e'
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
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)
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
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
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
140def get_pp_setup(setup) -> Tuple[dict, Sequence[int]]:
141 """
142 Get the pseudopotential mapping based on the "setpus" input.
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
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 = []
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()
169 # Default to minimal basis
170 if setup is None:
171 setup = {'base': 'minimal'}
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}
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 = {}
184 # Override defaults with user-defined setups
185 if setup is not None:
186 setups.update(setup)
188 for m in setups:
189 try:
190 special_setups.append(int(m))
191 except ValueError:
192 pass
193 return setups, special_setups
196def format_kpoints(kpts, atoms, reciprocal=False, gamma=False):
197 tokens = []
198 append = tokens.append
200 append('KPOINTS created by Atomic Simulation Environment\n')
202 if isinstance(kpts, dict):
203 kpts = kpts2ndarray(kpts, atoms=atoms)
204 reciprocal = True
206 shape = np.array(kpts).shape
208 # Wrap scalar in list if necessary
209 if shape == ():
210 kpts = [kpts]
211 shape = (1, )
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)
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.
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]
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]
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]
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]
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]
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]
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]
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]
964special_keys = [
965 'lreal', # non-local projectors in real space
966]
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]
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]
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 }
1192 # environment variable for PP paths
1193 VASP_PP_PATH = 'VASP_PP_PATH'
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
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."
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])
1284 def set(self, **kwargs):
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}}''')
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)
1349 def check_xc(self):
1350 """Make sure the calculator has functional & pseudopotentials set up
1352 If no XC combination, GGA functional or POTCAR type is specified,
1353 default to PW91. Otherwise, try to guess the desired pseudopotentials.
1354 """
1356 p = self.input_params
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 )
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")
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()))
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)
1399 # Create sorting list
1400 srt = [] # type: List[int]
1401 srt.extend(special_setups)
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
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)
1423 def _build_pp_list(self,
1424 atoms,
1425 setups=None,
1426 special_setups: Sequence[int] = ()):
1427 """Build the pseudopotential lists"""
1429 p = self.input_params
1431 if setups is None:
1432 setups, special_setups = get_pp_setup(p['setups'])
1434 symbols, _ = count_symbols(atoms, exclude=special_setups)
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']
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)
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)
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)
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/
1497 No pseudopotential for {}!""".format(potcar, symbol))
1498 raise RuntimeError(msg)
1499 return ppp_list
1501 def initialize(self, atoms):
1502 """Initialize a VASP calculation
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
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/
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 """
1519 self.check_xc()
1520 self.atoms = atoms
1521 self.all_symbols = atoms.get_chemical_symbols()
1522 self.natoms = len(atoms)
1524 self._set_spinpol(atoms)
1526 setups, special_setups = get_pp_setup(self.input_params['setups'])
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)
1534 self.atoms_sorted = atoms[self.sort]
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]])
1545 # create pseudopotential list
1546 self.ppp_list = self._build_pp_list(atoms,
1547 setups=setups,
1548 special_setups=special_setups)
1550 self.converged = None
1551 self.setups_changed = None
1553 def default_nelect_from_ppp(self):
1554 """ Get default number of electrons from ppp_list and symbol_count
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
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)
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."""
1589 vdw_env = 'ASE_VASP_VDW'
1590 kernel = 'vdw_kernel.bindat'
1591 dst = os.path.join(directory, kernel)
1593 # No need to copy the file again
1594 if isfile(dst):
1595 return
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)
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)
1612 def clean(self):
1613 """Method which cleans up after a calculation.
1615 The default files generated by Vasp will be deleted IF this
1616 method is called.
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
1631 def write_incar(self, atoms, directory='./', **kwargs):
1632 """Writes the INCAR file."""
1633 incar_params = {}
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 }
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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)
1769 write_incar(directory=directory, parameters=incar_params)
1771 def write_kpoints(self, atoms=None, directory='./', **kwargs):
1772 """Writes the KPOINTS file."""
1774 if atoms is None:
1775 atoms = self.atoms
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
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)
1796 def write_potcar(self, suffix="", directory='./'):
1797 """Writes the POTCAR file."""
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)
1805 def write_sort_file(self, directory='./'):
1806 """Writes a sortings file.
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."""
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]))
1817 # The below functions are used to restart a calculation
1819 def read_incar(self, filename):
1820 """Method that imports settings from INCAR file.
1822 Typically named INCAR."""
1824 self.spinpol = False
1825 with open(filename) as fd:
1826 lines = fd.readlines()
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'
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}"')
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 ]
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 ]
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]
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]
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
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
1954 with open(filename) as fd:
1955 lines = fd.readlines()
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)
1975 def read_potcar(self, filename):
1976 """ Read the pseudopotential XC functional from POTCAR file.
1977 """
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
1988 if xc_flag is None:
1989 raise ValueError('LEXCH flag not found in POTCAR file.')
1991 # Values of parameter LEXCH and corresponding XC-functional
1992 xc_dict = {'PE': 'PBE', '91': 'PW91', 'CA': 'LDA'}
1994 if xc_flag not in xc_dict.keys():
1995 raise ValueError('Unknown xc-functional flag found in POTCAR,'
1996 ' LEXCH=%s' % xc_flag)
1998 self.input_params['pp'] = xc_dict[xc_flag]
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
2016def _args_without_comment(data, marks=['!', '#']):
2017 """Check split arguments list for a comment, return data up to marker
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.
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)]
2030def _from_vasp_bool(x):
2031 """Cast vasp boolean to Python bool
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.
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')
2047def _to_vasp_bool(x):
2048 """Convert Python boolean to string for VASP input
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.
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.'
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}"')
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
2094def count_symbols(atoms, exclude=()):
2095 """Count symbols in atoms object, excluding a set of indices
2097 Parameters:
2098 atoms: Atoms object to be grouped
2099 exclude: List of indices to be excluded from the counting
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
2106 Example:
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