diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..05e47c7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,139 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +~.py + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ diff --git a/scripts/vasprun b/scripts/vasprun index bd63d22..b3c56b9 100755 --- a/scripts/vasprun +++ b/scripts/vasprun @@ -43,6 +43,11 @@ if __name__ == "__main__": help="figure' dpi, default: 300", metavar="dpi") parser.add_option("-S", "--save-bands", dest="saveBands", action='store_true', help="saving of bands contributing to the plot, default: false", metavar="saveBands") + parser.add_option("-E", "--efermi", dest="fermiEnergy", default=None, + help="fermi energy setting, default: read from vasprun.xml", metavar="fermiEnergy") + parser.add_option('--labels', default=None, + help='Labels for each of high symmetry points. (e.g., \'$\Gamma$ X M\'; default None)') + (options, args) = parser.parse_args() if options.vasprun is None: @@ -102,14 +107,24 @@ if __name__ == "__main__": elif options.dosplot: lim = options.lim.split(',') lim = [float(i) for i in lim] - test.plot_dos(styles=options.dosplot, filename=options.figname, xlim=lim, smear=options.smear) + Ef = None + if options.fermiEnergy is not None: + Ef = float(options.fermiEnergy) + test.plot_dos(styles=options.dosplot, filename=options.figname, xlim=lim, smear=options.smear, fermiEnergy=Ef) elif options.bandplot: lim = options.lim.split(',') lim = [float(i) for i in lim] pmaxmin = options.max.split(',') pmaxmin = [float(i) for i in pmaxmin] test.parse_bandpath() - test.plot_band(styles=options.bandplot, filename=options.figname, ylim=lim, plim=pmaxmin, saveBands=options.saveBands, dpi=options.dpi) + Ef = None + if options.labels: + kTags = options.labels.split() + else: + kTags = None + if options.fermiEnergy is not None: + Ef = float(options.fermiEnergy) + test.plot_band(styles=options.bandplot, filename=options.figname, ylim=lim, plim=pmaxmin, fermiEnergy=Ef, saveBands=options.saveBands, dpi=options.dpi, kTags=kTags) elif options.band: vb = test.values['bands']-1 cb = vb + 1 diff --git a/vasprun/__init__.py b/vasprun/__init__.py index aa0f13f..65e3e52 100644 --- a/vasprun/__init__.py +++ b/vasprun/__init__.py @@ -8,6 +8,7 @@ import pandas as pd from tabulate import tabulate import warnings +from scipy import constants import matplotlib as mpl mpl.use("Agg") @@ -32,15 +33,15 @@ def smear_data(data, sigma): return data class units: - am2kg = 1.6605402e-27 - ev2j = 1.60217733e-19 - plank = 6.626075e-34 - c = 2.99792458e+10 - pi = 3.1415926 - proton_mass = 1836 - ev2hartree = 27.211386245988 - a2bohr = 0.529 - ev2cm = 8065.6 + pi = constants.pi #3.1415926 + am2kg = constants.physical_constants['atomic mass constant'][0] #1.6605402e-27 + ev2j = constants.physical_constants['electron volt-joule relationship'][0] #1.60217733e-19 + plank = constants.physical_constants['Planck constant'][0] #6.626075e-34 + c = 1e2*constants.physical_constants['speed of light in vacuum'][0] #2.99792458e+10 in cm/s? + proton_mass = constants.physical_constants['proton-electron mass ratio'][0] #1836 + ev2hartree = constants.physical_constants['Hartree energy in eV'][0] #27.211386245988 + a2bohr = 1e10*constants.physical_constants['Bohr radius'][0] #0.529 + ev2cm = 1e-2*constants.physical_constants['electron volt-inverse meter relationship'][0] #8065.6 class vasprun: """ @@ -686,7 +687,7 @@ def inline(kpt, path): self.values['band_paths'] = band_paths self.values['band_points'] = band_points - def plot_band(self, filename=None, styles='normal', ylim=[-20, 3], plim=[0.0,0.5], saveBands=False, dpi=300): + def plot_band(self, filename=None, styles='normal', ylim=[-20, 3], plim=[0.0,0.5], fermiEnergy=None, saveBands=False, dpi=300, kTags=None): """ plot the bandstructure @@ -695,17 +696,22 @@ def plot_band(self, filename=None, styles='normal', ylim=[-20, 3], plim=[0.0,0.5 styles: string (`normal` or `projected`) ylim: list, the range of energy values on the y-axis, e.g. [-5, 3] p_max: float (the ratio of color plot in the `projected` mode) + fermiEnergy: Band Structure calculations do not contain the proper Fermi energy + - it needs to be set by hand for precise calculations Returns: A figure with band structure """ self.parse_bandpath() - efermi = self.values["calculation"]["efermi"] - eigens = np.array(self.values['calculation']['eband_eigenvalues']) - paths = self.values['band_paths'] - band_pts = self.values['band_points'] - proj = np.array(self.values["calculation"]["projected"]) #[N_kpts, N_band, Ions, 9] - cm = plt.cm.get_cmap('RdYlBu') + if fermiEnergy is None: + efermi = self.values["calculation"]["efermi"] + else: + efermi = fermiEnergy + eigens = np.array(self.values['calculation']['eband_eigenvalues']) + paths = self.values['band_paths'] + band_pts = self.values['band_points'] + proj = np.array(self.values["calculation"]["projected"]) #[N_kpts, N_band, Ions, 9] + cm = plt.cm.get_cmap('RdYlBu') nkpt, nband, nocc = np.shape(eigens) for i in range(nband): band = eigens[:, i, 0] - efermi @@ -755,8 +761,12 @@ def get_dos(self, rows, style='t'): N_atom = len(a_array) tdos = np.array(self.values['calculation']['tdos']) pdos = np.array(self.values['calculation']['pdos']) - a, b, c, d = np.shape(pdos) - pdos = np.reshape(pdos, [b, a, c, d]) + try: + a, b, c, d = np.shape(pdos) + pdos = np.reshape(pdos, [b, a, c, d]) + except ValueError as error: + if style != 't': + raise error if style == 't': for spin in tdos: mydos.append(spin[rows, 1]) @@ -801,7 +811,7 @@ def get_dos(self, rows, style='t'): mydos[1] *= -1 return mydos, labels - def plot_dos(self, filename=None, smear=None, styles='t', xlim=[-3, 3], dpi=300): + def plot_dos(self, filename=None, smear=None, fermiEnergy=None, styles='t', xlim=[-3, 3], dpi=300): """ plot the DOS @@ -810,11 +820,16 @@ def plot_dos(self, filename=None, smear=None, styles='t', xlim=[-3, 3], dpi=300) styles: string (`t` or `s` or `t+spd`) xlim: list, the range of energy values on the x-axis, e.g. [-5, 3] smear: float (the width of smearing, defult: None) + fermiEnergy: Band Structure calculations do not contain the proper Fermi energy + - it needs to be set by hand for precise calculations Returns: A figure with band structure """ - efermi = self.values['calculation']['efermi'] + if fermiEnergy is None: + efermi = self.values["calculation"]["efermi"] + else: + efermi = fermiEnergy tdos = np.array(self.values['calculation']['tdos'][0]) tdos[:, 0] -= efermi e = tdos[:, 0]