Source code for pyprocar.scriptFermi2D

from .utilsprocar import UtilsProcar
from .procarparser import ProcarParser
from .procarselect import ProcarSelect
from .procarplot import ProcarPlot
from .procarsymmetry import ProcarSymmetry
from .fermisurface import FermiSurface
from .elkparser import ElkParser
from .abinitparser import AbinitParser
import matplotlib.pyplot as plt
from .splash import welcome


[docs]def fermi2D( file, outcar=None, abinit_output=None, spin=0, atoms=None, orbitals=None, energy=None, fermi=None, rec_basis=None, rot_symm=1, translate=[0, 0, 0], rotation=[0, 0, 0, 1], human=False, mask=None, savefig=None, st=False, noarrow=False, exportplt=False, code="vasp", repair=True, ): """ This module plots 2D Fermi surface. """ welcome() # Turn interactive plotting off plt.ioff() # Repair PROCAR if code == "vasp" or code == "abinit": if repair: repairhandle = UtilsProcar() repairhandle.ProcarRepair(file, file) print("PROCAR repaired. Run with repair=False next time.") if atoms is None: atoms = [-1] if human is True: print("WARNING: `--human` option given without atoms list!!!!!") if orbitals is None: orbitals = [-1] if rec_basis != None: rec_basis = np.array(rec_basis) rec_basis.shape = (3, 3) if len(translate) != 3 and len(translate) != 1: print("Error: --translate option is invalid! (", translate, ")") raise RuntimeError("invalid option --translate") print("file : ", file) print("outcar : ", outcar) print("Abinit output : ", abinit_output) print("atoms : ", atoms) print("orbitals : ", orbitals) print("spin comp. : ", spin) print("energy : ", energy) print("fermi energy : ", fermi) print("Rec. basis : ", rec_basis) print("rot. symmetry : ", rot_symm) print("origin (trasl.) : ", translate) print("rotation : ", rotation) print("masking thres. : ", mask) print("save figure : ", savefig) print("st : ", st) print("no_arrows : ", noarrow) # first parse the outputs if given if code == "vasp": if rec_basis is None and outcar: outcarparser = UtilsProcar() if fermi is None: fermi = outcarparser.FermiOutcar(outcar) print("Fermi energy found in outcar file = " + str(fermi)) rec_basis = outcarparser.RecLatOutcar(outcar) # Reciprocal lattices are needed! elif rec_basis is None and outcar is None: print("ERROR: Reciprocal Lattice is needed, use --rec_basis or --outcar") raise RuntimeError("Reciprocal Lattice not found") # parsing the file procarFile = ProcarParser() # permissive incompatible with Fermi surfaces procarFile.readFile(file, permissive=False, recLattice=rec_basis) elif code == "elk": procarFile = ElkParser() if rec_basis is None: if fermi is None: fermi = procarFile.fermi print("Fermi energy found in Elk output file = " + str(fermi)) rec_basis = procarFile.reclat # Reciprocal lattices are needed! if rec_basis is None: print("ERROR: Reciprocal Lattice is needed, use --rec_basis or --outcar") raise RuntimeError("Reciprocal Lattice not found") procarFile = Elkparser(kdirect=False) elif code == "abinit": if rec_basis is None and abinit_output: abinitparser = AbinitParser(abinit_output=abinit_output) if fermi is None: fermi = abinitparser.fermi print("Fermi energy found in Abinit ouput file = " + str(fermi)) rec_basis = abinitparser.reclat # Reciprocal lattices are needed! elif rec_basis is None and abinit_output is None: print("ERROR: Reciprocal Lattice is needed, use --rec_basis or --outcar") raise RuntimeError("Reciprocal Lattice not found") # parsing the file procarFile = ProcarParser() # permissive incompatible with Fermi surfaces procarFile.readFile(file, permissive=False, recLattice=rec_basis) ### End of parsing ### if st is not True: # processing the data data = ProcarSelect(procarFile) data.selectIspin([spin]) # fortran flag is equivalent to human, # but the later seems more human-friendly data.selectAtoms(atoms, fortran=human) data.selectOrbital(orbitals) else: # first get the sdp reduced array for all spin components. stData = [] for i in [1, 2, 3]: data = ProcarSelect(procarFile) data.selectIspin([i]) data.selectAtoms(atoms, fortran=human) data.selectOrbital(orbitals) stData.append(data.spd) # Once the PROCAR is parsed and reduced to 2x2 arrays, we can apply # symmetry operations to unfold the Brillouin Zone kpoints = data.kpoints bands = data.bands character = data.spd if st is True: sx, sy, sz = stData[0], stData[1], stData[2] symm = ProcarSymmetry(kpoints, bands, sx=sx, sy=sy, sz=sz, character=character) else: symm = ProcarSymmetry(kpoints, bands, character=character) symm.Translate(translate) symm.GeneralRotation(rotation[0], rotation[1:]) # symm.MirrorX() symm.RotSymmetryZ(rot_symm) # plotting the data print("Bands will be shifted by the Fermi energy = ", fermi) fs = FermiSurface(symm.kpoints, symm.bands - fermi, symm.character) fs.FindEnergy(energy) if not st: fs.Plot(mask=mask, interpolation=300) else: fs.st(sx=symm.sx, sy=symm.sy, sz=symm.sz, noarrow=noarrow, spin=spin) if exportplt: return plt else: if savefig: plt.savefig(savefig, bbox_inches="tight") plt.close() # Added by Nicholas Pike to close memory issue of looping and creating many figures else: plt.show() return