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