Source code for dfttools.parsers.vasp

"""
Parsing `VASP <https://www.vasp.at/>`_ files.
"""
import numericalunits

from .generic import AbstractParser
from ..simple import band_structure, unit_cell
from ..types import Basis, UnitCell

[docs]class Output(AbstractParser): """ Class for parsing VASP OUTCAR. Args: data (string): contents of OUTCAR file """ @staticmethod def valid_header(header): return header.startswith(" vasp.5.4") @staticmethod def valid_filename(name): return name == "OUTCAR"
[docs] def fermi(self): """ Retrieves Fermi energies. Returns: A numpy array containing Fermi energies for each MD step. """ self.parser.reset() result = [] while self.parser.present("E-fermi :"): self.parser.skip("E-fermi :") result.append(self.parser.nextFloat()*numericalunits.eV) return result
def __reciprocal__(self): self.parser.skip("reciprocal lattice vectors") self.parser.nextLine() return Basis( self.parser.nextFloat((3,6))[:,3:], ) def __kpoints__(self): self.parser.skip("k-points in reciprocal lattice and weights: K-points") return self.parser.nextFloat("\n \n").reshape(-1,4)[:,:3] @band_structure
[docs] def bands(self): """ Retrieves bands. Returns: A UnitCells with the band structure. """ self.parser.reset() basis = self.__reciprocal__() k = self.__kpoints__() self.parser.skip("E-fermi :") fermi = self.parser.nextFloat()*numericalunits.eV e = [] for i in range(len(k)): self.parser.skip("k-point") self.parser.skip(str(i+1)) self.parser.nextLine(2) e.append(self.parser.nextFloat("\n\n").reshape(-1,3)[:,1]*numericalunits.eV) result = UnitCell( basis, k, e, ) result.meta["Fermi"] = fermi return result
[docs]class Structure(AbstractParser): """ Class for parsing VASP POSCAR. Args: data (string): contents of OUTCAR file """ def unitCell(self, names): self.parser.reset() self.parser.nextLine() scale = self.parser.nextFloat() self.parser.nextLine() vectors = self.parser.nextFloat((3,3)) basis = Basis(vectors, units = "angstrom") if scale>0: scale *= numericalunits.angstrom else: raise NotImplemented basis.vectors *= scale self.parser.nextLine(2) nat = self.parser.nextInt("\n") self.parser.nextLine() l = self.parser.nextLine().lower() if l[0] == 'c' or l[0] == 'k': c_basis = 'cartesian' else: c_basis = None coords = self.parser.nextFloat((sum(nat),3)) atoms = [] for name, number in zip(names, nat): atoms += [name]*number return UnitCell( basis, coords if c_basis is None else coords*scale, atoms, c_basis = c_basis, )