Source code for storq.vasp.validate

import ase
import numpy as np
import types
import warnings
from ase.calculators import calculator
from ase.utils import basestring
from typing import Union, List


[docs]def algo(calc, val): """ specify the electronic minimisation algorithm (as of VASP.4.5) (string) http://cms.mpi.univie.ac.at/wiki/index.php/ALGO """ assert isinstance(val, str) assert val.lower() in [ x.lower() for x in [ "Normal", "VeryFast", "Fast", "Conjugate", "All", "Damped", "Subrot", "Eigenval", "None", "Nothing", "CHI", "GW0", "GW", "scGW0", "scGW", ]
]
[docs]def atoms(calc, val): """The Atoms object. (ase.atoms.Atoms)."""
assert isinstance(val, ase.atoms.Atoms)
[docs]def eb_k(calc, val): """The relative permittivity of the solvent used in the VASPsol code. (float) https://github.com/henniggroup/VASPsol/blob/master/docs/USAGE.md """
assert isinstance(val, float)
[docs]def ediff(calc, val): """EDIFF specifies the global break condition for the electronic loop. (float) http://cms.mpi.univie.ac.at/wiki/index.php/EDIFF """
assert isinstance(val, float) or val == 0
[docs]def ediffg(calc, val): """EDIFFG defines the break condition for the ionic relaxation loop. (float) If EDIFFG < 0, it defines a force criteria. http://cms.mpi.univie.ac.at/wiki/index.php/EDIFFG """
assert isinstance(val, float) or val == 0
[docs]def encut(calc, val): """Planewave cutoff in eV. (float) http://cms.mpi.univie.ac.at/wiki/index.php/ENCUT """ assert val > 0, "encut must be greater than zero." assert isinstance(val, int) or isinstance(val, long) or isinstance(val, float), ( "encut should be an int or float." " You provided {} ({}).".format(val, type(val))
)
[docs]def ialgo(calc, val): """ `IALGO <http://cms.mpi.univie.ac.at/wiki/index.php/IALGO>`_ selects the algorithm used to optimize the orbitals. """ print("You are advised to use the algo key instead of ialgo.") assert isinstance(val, int) assert val in [ -1, 2, 3, 4, 5, 6, 7, 8, 15, 16, 17, 18, 28, 38, 44, 45, 46, 47, 48, 53, 54, 55, 56, 57, 58,
]
[docs]def ibrion(calc, val): """`IBRION <http://cms.mpi.univie.ac.at/wiki/index.php/IBRION>`_ determines the algorithm to update geometry during relaxtion. (int) """
assert val in [-1, 0, 1, 2, 3, 5, 6, 7, 8, 44]
[docs]def icharg(calc, val): """Determines how VASP constructs the `initial charge density <http://cms.mpi.univie.ac.at/wiki/index.php/ICHARG>`_. ===== =================================================== Value Meaning ===== =================================================== 0 calculate from initial wave functions 1 read from the CHGCAR 2 (default) Superposition of atomic charge densities 11 for band-structure plots ===== =================================================== Parameters ---------- val : int new value """
assert isinstance(val, int)
[docs]def images(calc, val): """ `The number of images <http://cms.mpi.univie.ac.at/wiki/index.php/IMAGES>`_ for a nudge elastic band (NEB) calculation not counting the end points. Parameters ---------- val : int new value """ assert isinstance(val, int)
assert val == len(calc.neb) - 2
[docs]def isif(calc, val): """ISIF determines what is changed during relaxations. ====== =========== =============== ======= ============ ============= ISIF calculate calculate relax change change force stress tensor ions cell shape cell volume ====== =========== =============== ======= ============ ============= 0 yes no yes no no 1 yes trace only yes no no 2 yes yes yes no no 3 yes yes yes yes yes 4 yes yes yes yes no 5 yes yes no yes no 6 yes yes no yes yes 7 yes yes no no yes ====== =========== =============== ======= ============ ============= Parameters ---------- val : int new value """
assert val in [0, 1, 2, 3, 4, 5, 6, 7]
[docs]def ismear(calc, val): """ `ISMEAR <http://cms.mpi.univie.ac.at/wiki/index.php/ISMEAR>`_ determines how the partial occupancies are set. Parameters ---------- val : int new value """
assert val in [-5, -4, -3, -2, -1, 0, 1, 2]
[docs]def ispin(calc, val): """`Control spin-polarization <http://cms.mpi.univie.ac.at/wiki/index.php/ISPIN>`_. ===== ============================== Value Meaning ===== ============================== 1 default, no spin polarization 2 spin-polarization. ===== ============================== Parameters ---------- val : int new value """ assert val in [1, 2], "ispin should be 1 or 2" if val == 2: assert "magmom" in calc.parameters, "magmom is not set." assert len(calc.parameters["magmom"]) == len( calc.get_atoms()
), "len(magmom) != len(atoms)"
[docs]def isym(calc, val): """ISYM determines the way VASP treats symmetry. http://cms.mpi.univie.ac.at/wiki/index.php/ISYM """
assert val in [-1, 0, 1, 2, 3]
[docs]def ivdw(calc, val): """`IVDW <http://cms.mpi.univie.ac.at/vasp/vasp/IVDW_approximate_vdW_correction_methods.html>`_ determines the approximate vdW correction methods used. ===== ================================================================================================ Value Meaning ===== ================================================================================================ 0 no correction 1|10 DFT-D2 method of Grimme (available as of VASP.5.2.11) 11 zero damping DFT-D3 method of Grimme (available as of VASP.5.3.4) 12 DFT-D3 method with Becke-Jonson damping (available as of VASP.5.3.4) 2 Tkatchenko-Scheffler method (available as of VASP.5.3.3) 21 Tkatchenko-Scheffler method with iterative Hirshfeld partitioning (available as of VASP.5.3.5) 202 Many-body dispersion energy method (MBD@rSC) (available as of VASP.5.4.1) 4 dDsC dispersion correction method (available as of VASP.5.4.1) ===== ================================================================================================ Parameters ---------- val : int new value """
assert val in [0, 1, 10, 11, 12, 2, 21, 202, 4]
[docs]def ldau(calc, val): """`LDAU <http://cms.mpi.univie.ac.at/wiki/index.php/LDAU>`_ switches on the L(S)DA+U. Parameters ---------- val : bool new value """
assert val in [True, False, None]
[docs]def ldau_luj(calc, val): """ Dictionary of DFT+U parameters:: ldau_luj={'Mn': {'L': 2, 'U': 0.0, 'J': 0.0}, 'O': {'L': -1, 'U': 0.0, 'J': 0.0}}, """ assert isinstance(val, dict) # this may not be the case for site-specific U. I think we need # setups for that.
assert len(val.keys()) == len(set([a.symbol for a in calc.get_atoms()]))
[docs]def ldauprint(calc, val): """`LDAUPRINT <http://cms.mpi.univie.ac.at/wiki/index.php/LDAUPRINT>`_ controls the verbosity of the L(S)DA+U routines. ===== ============================================================== Value Meaning ===== ============================================================== 0 silent. 1 Write occupancy matrix to the OUTCAR file. 2 same as LDAUPRINT=1, plus potential matrix dumped to vasp_stdout ===== ============================================================== Parameters ---------- val : int new value """
assert val in [0, 1, 2]
[docs]def ldautype(calc, val): """`LDAUTYPE <http://cms.mpi.univie.ac.at/wiki/index.php/LDAUTYPE>`_ specifies which type of L(S)DA+U approach will be used. ``LDAUTYPE=1``: Rotationally invariant LSDA+U [1] ``LDAUTYPE=2``: Simplified (rotationally invariant) LSDA+U [2] 1. A. I. Liechtenstein, V. I. Anisimov and J. Zaane, Phys. Rev. B **52**, R5467 (1995). 2. S. L. Dudarev, G. A. Botton, S. Y. Savrasov, C. J. Humphreys and A. P. Sutton, Phys. Rev. B **57**, 1505 (1998). Parameters ---------- val : int new value
"""
[docs]def lmaxmix(calc, val): """`LMAXMIX <http://cms.mpi.univie.ac.at/wiki/index.php/LMAXMIX>`_ the max l-quantum number the charge densities used. Mostly used for DFT+U. 4 for d-electrons (or 6 for f-elements) Parameters ---------- val : int new value """
assert val in [2, 4, 6]
[docs]def kpts(calc, val): """Sets k-points. Not a Vasp keyword. (list or dict)""" assert isinstance(val, list) or isinstance( val, dict ), "kpts must be a list or a dict." if isinstance(val, dict): assert ( len([1 for key in val if key in ["size", "spacing", "auto", "list"]]) == 1 ), "kpts dict must only contain one of the keys size/spacing/auto/list" if isinstance(val, list): assert len(val) == 3 or ( len(np.array(val).shape) == 2 and np.array(val).shape[1] == 3 ), """kpts list must be either three ints specifying divisions or an
explicit list of k-points"""
[docs]def kspacing(calc, val): """`KSPACING <http://cms.mpi.univie.ac.at/vasp/vasp/KSPACING_tag_KGAMMA_tag.html>`_ determines the number of k-points if the KPOINTS file is not present. Parameters ---------- val : float new value """
assert isinstance(val, float)
[docs]def lcharg(calc, val): """`LCHARG <http://cms.mpi.univie.ac.at/wiki/index.php/LCHARG>`_ determines whether CHGCAR and CHG are written. Parameters ---------- val : bool new value """
assert val in [True, False]
[docs]def lorbit(calc, val): """`Determines whether the PROCAR or PROOUT files are written <http://cms.mpi.univie.ac.at/wiki/index.php/LORBIT>`_. Parameters ---------- val : int new value """ if val < 10: assert "rwigs" in calc.parameters
assert isinstance(val, int)
[docs]def lsol(calc, val): """`LSOL <https://github.com/henniggroup/VASPsol/blob/master/docs/USAGE.md>`_ determines whether the VASPsol is activated. Parameters ---------- val : bool new value """
assert val in [True, False]
[docs]def lreal(calc, val): """`LREAL <http://cms.mpi.univie.ac.at/wiki/index.php/LREAL>`_ determines whether the projection operators are evaluated in real-space or in reciprocal space. Parameters ---------- val : bool/string new value """
assert val in [True, False, "On", "Auto", "O", "A"]
[docs]def lwave(calc, val): """`LWAVE <http://cms.mpi.univie.ac.at/wiki/index.php/LWAVE>`_ determines whether the WAVECAR is written. Parameters ---------- val : bool new value """
assert val in [True, False]
[docs]def magmom(calc: calculator, val: Union[List[int], np.ndarray]): """`MAGMOM <http://cms.mpi.univie.ac.at/wiki/index.php/MAGMOM>`_ specifies the initial magnetic moment for each atom. Raises ------ TypeError if the input value is neither a list nor a numpy array ValueError if the length of the input list does not match the number of atoms of the structure associated with the calculator """ if not isinstance(val, (list, np.ndarray)): raise TypeError( "magmom must be a list or a numpy array yet" " type(magmom)= {}\nmagmom: {}".format(type(val), val) ) if len(val) != len(calc.atoms): raise ValueError( "Number of elements in magmom ({}) does not match the" " number of atoms in the structure associated with the" " calculator ({})".format(len(val), len(calc.atoms))
)
[docs]def maxmix(calc, val): """`MAXMIX <http://cms.mpi.univie.ac.at/wiki/index.php/MAXMIX>`_ specifies the maximum number steps stored in Broyden mixer (IMIX=4). Parameters ---------- val : int new value """
assert isinstance(val, int)
[docs]def nbands(calc, val): """`NBANDS <http://cms.mpi.univie.ac.at/wiki/index.php/NBANDS>`_ determines the actual number of bands in the calculation. Parameters ---------- val : int new value """ assert isinstance(val, int) or isinstance(val, long) s = "nbands = {} which is less than {}." assert val > calc.get_valence_electrons() / 2, s.format( val, calc.get_valence_electrons() / 2
)
[docs]def ncore(calc, val): """`NCORE <http://cms.mpi.univie.ac.at/wiki/index.php/NCORE>`_ determines the number of compute cores that work on an individual orbital. Parameters ---------- val : int new value """
assert isinstance(val, int)
[docs]def nelm(calc, val): """`NELM <http://cms.mpi.univie.ac.at/wiki/index.php/NELM>`_ sets the maximum number of electronic SC (selfconsistency) steps which may be performed. Parameters ---------- val : int new value """
assert isinstance(val, int)
[docs]def nupdown(calc, val): """`NUPDOWN <http://cms.mpi.univie.ac.at/vasp/vasp/NUPDOWN.html>`_ sets the difference between the number of spin up and down electrons. This fixes the bulk magnetic moment. The VASP manual specifies this should be an integer, but it appears floats work too. Parameters ---------- val : int/float new value """
assert isinstance(val, int) or isinstance(val, float)
[docs]def nsw(calc, val): """`NSW <http://cms.mpi.univie.ac.at/wiki/index.php/NSW>`_ sets the maximum number of ionic steps. Parameters ---------- val : int new value """
assert isinstance(val, int)
[docs]def potim(calc, val): """`POTIM <http://cms.mpi.univie.ac.at/wiki/index.php/POTIM>`_ sets the time step (MD) or step width scaling (ionic relaxations). Parameters ---------- val : float new value """
assert isinstance(val, float)
[docs]def pp(calc, val): """ Determines where POTCARS are retrieved from. Parameters ---------- val : string new value """
assert val in ["PBE", "LDA", "GGA"]
[docs]def prec(calc, val): """Specifies the `precision vasp_mode <http://cms.mpi.univie.ac.at/wiki/index.php/PREC>`_. Parameters ---------- val : string new value """
assert val in ["Low", "Medium", "High", "Normal", "Accurate", "Single"]
[docs]def rwigs(calc, val): """`RWIGS <http://cms.mpi.univie.ac.at/wiki/index.php/RWIGS>`_ specifies the Wigner-Seitz radius for each atom type. in vasp.py you enter a dictionary of:: {sym: radius} Parameters ---------- val : list new value """ assert isinstance(val, list)
assert calc.parameters.get("lorbit", 0) < 10, "lorbit >= 10, rwigs is ignored."
[docs]def setups(calc, val): """Sets up special setups for the POTCARS (list of (symbol/int, suffix)). The first element of each pair of the list is either an integer index of the atom for the special setup, or a chemical symbol for all atoms of that type. The second element of the pair is a suffix to be appended to the symbol. For example, to use the O_s potcar set setups to: [['O', '_s']]. This is not a vasp keyword. """ assert isinstance(val, list) for s, suffix in val: assert isinstance(s, int) or isinstance(s, basestring)
assert isinstance(suffix, basestring)
[docs]def sigma(calc, val): """SIGMA determines the width of the smearing in eV. (float)""" assert isinstance(val, float)
assert val > 0
[docs]def spring(calc, val): """The Spring constant in the elastic band method. -5 = NEB. http://cms.mpi.univie.ac.at/wiki/index.php/SPRING """ assert isinstance(val, int) or isinstance(val, float) if calc.parameters.get("ibrion") not in [1, 3]:
warnings.warn("ibrion should be 1 or 3.")
[docs]def xc(calc, val): """Set exchange-correlation functional. (string)""" from storq.vasp.core import Vasp assert val.lower() in Vasp._xc_defaults.keys(), "xc ({}) not in {}.".format( val, Vasp._xc_defaults.keys()
)
[docs]def addgrid(calc, val): """ADDGRID gives an extra grid for the evaluation of augmentation charges."""
assert val in [True, False]
[docs]def luse_vdw(calc, val): """luse_vdw turns on vdW-DF by Langreth and Lundqvist"""
assert val in [True, False]
[docs]def aggac(calc, val): """Fraction of gradient correction to correlation in a hybrid calculation""" assert isinstance(val, float) aggac = calc.parameters.get("aggac", None) if aggac is not None and not np.isclose(aggac, 0.0):
warnings.warn("aggac must be 0.0.")
[docs]def gga(calc, val): """Grants access to certain special GGAs """
assert isinstance(val, basestring) or val == 91
[docs]def nsim(calc, val): """Sets block size for the RMM-DIIS algorithm"""
assert isinstance(val, int) and val > 0
[docs]def kpar(calc, val): """Control parallelization over k-points"""
assert isinstance(val, int) and val > 0
[docs]def npar(calc, val): """Determines how many bands are run in parallel"""
assert isinstance(val, int) and val > 0
[docs]def keywords(): """Return list of keywords we vasp_validate. Returns a lisp list for Emacs. """ import vasp_validate f = [ vasp_validate.__dict__.get(a) for a in dir(vasp_validate) if isinstance(vasp_validate.__dict__.get(a), types.FunctionType) ] names = [x.__name__ for x in f] names.remove("keywords")
return "(" + " ".join(['"{}"'.format(x) for x in names]) + ")"
[docs]def keyword_alist(): """Returns an alist of (keyword . "first doc string"). Returns the alist for use in Emacs. """ import vasp_validate f = [ vasp_validate.__dict__.get(a) for a in dir(vasp_validate) if isinstance(vasp_validate.__dict__.get(a), types.FunctionType) ] names = [x.__name__ for x in f] names.remove("keywords") names.remove("keyword_alist") docstrings = [vasp_validate.__dict__[name].__doc__.split("\n")[0] for name in names] cons_cells = [ '("{}" "{}")'.format(key, doc) for key, doc in zip(names, docstrings) ]
return "(" + "".join(cons_cells) + ")"