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