Source code for spinney.io.vasp
# -*- coding: utf-8 -*-
""" Helper functions for VASP postprocessing """
import re
import numpy as np
[docs]def extract_potential_at_core_vasp(file):
"""
Read the VASP OUTCAR file and extract the values of the electrostatic
potential evaluated at the ions positions.
Parameters
----------
file : string
path to the OUTCAR file
Returns
-------
result : 1D numpy array
for each atom in the system, returns the electrostatic
potential at the atomic sites
"""
look = 'average (electrostatic) potential at core'
pots = []
with open(file) as f:
for line in f:
line = line.strip()
if line == look:
pot = []
next(f)
next(f)
while True:
lline = f.readline().strip().split()
if lline and lline[0] == 'E-fermi':
break
elif lline:
for x in lline:
pot.append(x)
# flip the sign as for VASP returns the
# potential energy where the electron
# charge has magnitude 1
pots.append(-np.array(pot[1::2]).astype(np.float64))
return pots[-1]
[docs]def extract_dos(vasprun_file, save_dos=False):
""" From the vasprun.xml file extrat the DOS.
Parameters
----------
vasprun_file : string
path to the vasprun.xml file
save_dos : bool
if True, the extracted DOS are saved as a text file.
The first column is the energy (in eV) and the second
the DOS (states/cell)
Returns
-------
dos : 2-ple, the DOS up and DOS down (if any)
each element is a 2D numpy array.
First column
"""
vasprun = vasprun_file
ispin = False
regex = 'ISPIN.+([1-2])'
with open(vasprun, 'r') as stream:
e1 = []
dos1 = []
e2 = []
dos2 = []
while True:
line = next(stream)
line = line.strip('\n').strip()
if re.findall(regex, line):
isvalue = re.findall(regex, line)[0]
if isvalue == 2:
ispin = True
if line == '<dos>':
break
line = next(stream)
e_fermi = line.strip('\n').strip().split()[-2]
for i in range(9):
next(stream)
stop = False
while not stop:
line = next(stream)
line = line.strip('\n').strip()
if line == '</set>':
stop = True
else:
line = line.split()
e1.append(float(line[1]))
dos1.append(float(line[2]))
if ispin:
next(stream)
stop = False
while not stop:
line = next(stream)
line = line.strip('\n').strip()
if line == '</set>':
stop = True
else:
line = line.split()
e2.append(float(line[1]))
dos2.append(float(line[2]))
dos_up = np.c_[e1, dos1]
dos_down = np.c_[e2, dos2]
if save_dos:
print('\nFermi level = ', e_fermi)
np.savetxt('dos_up.txt', dos_up, delimiter=' ')
np.savetxt('dos_down.txt', dos_down, delimiter=' ')
return (dos_up, dos_down)