def get_band_structure(self): """Return a BandStructureSymmLine object interpolating bands along a High symmetry path calculated from the structure using HighSymmKpath function""" kpath = HighSymmKpath(self.data.structure) kpt_line = [ Kpoint(k, self.data.structure.lattice) for k in kpath.get_kpoints(coords_are_cartesian=False)[0] ] kpoints = np.array([kp.frac_coords for kp in kpt_line]) labels_dict = { l: k for k, l in zip(*kpath.get_kpoints(coords_are_cartesian=False)) if l } lattvec = self.data.get_lattvec() egrid, vgrid = fite.getBands(kpoints, self.equivalences, lattvec, self.coeffs) bands_dict = {Spin.up: (egrid / units.eV)} sbs = BandStructureSymmLine( kpoints, bands_dict, self.data.structure.lattice.reciprocal_lattice, self.efermi / units.eV, labels_dict=labels_dict) return sbs
def get_band_structure(self): """Return a BandStructureSymmLine object interpolating bands along a High symmetry path calculated from the structure using HighSymmKpath function""" kpath = HighSymmKpath(self.data.structure) kpt_line = [Kpoint(k, self.data.structure.lattice) for k in kpath.get_kpoints(coords_are_cartesian=False)[ 0]] kpoints = np.array( [kp.frac_coords for kp in kpt_line]) labels_dict = {l: k for k, l in zip( *kpath.get_kpoints(coords_are_cartesian=False)) if l} lattvec = self.data.get_lattvec() egrid, vgrid = fite.getBands(kpoints, self.equivalences, lattvec, self.coeffs) bands_dict = {Spin.up: (egrid / units.eV)} sbs = BandStructureSymmLine(kpoints, bands_dict, self.data.structure.lattice.reciprocal_lattice, self.efermi / units.eV, labels_dict=labels_dict) return sbs
def get_symmetry_points(fermi_surface) -> Tuple[np.ndarray, List[str]]: """ Get the high symmetry k-points and labels for the Fermi surface. Args: fermi_surface: A fermi surface. Returns: The high symmetry k-points and labels. """ kpoints, labels = [], [] hskp = HighSymmKpath(fermi_surface.structure) all_kpoints, all_labels = hskp.get_kpoints(coords_are_cartesian=False) for kpoint, label in zip(all_kpoints, all_labels): if not len(label) == 0: kpoints.append(kpoint) labels.append(label) if isinstance(fermi_surface.reciprocal_space, ReciprocalCell): kpoints = kpoints_to_first_bz(np.array(kpoints)) kpoints = np.dot(kpoints, fermi_surface.reciprocal_space.reciprocal_lattice) return kpoints, labels
def test_kpath_generation(self): triclinic = [1, 2] monoclinic = range(3, 16) orthorhombic = range(16, 75) tetragonal = range(75, 143) rhombohedral = range(143, 168) hexagonal = range(168, 195) cubic = range(195, 231) species = ["K", "La", "Ti"] coords = [[0.345, 5, 0.77298], [0.1345, 5.1, 0.77298], [0.7, 0.8, 0.9]] for i in range(230): sg_num = i + 1 if sg_num in triclinic: lattice = Lattice( [[3.0233057319441246, 1, 0], [0, 7.9850357844548681, 1], [0, 1.2, 8.1136762279561818]] ) elif sg_num in monoclinic: lattice = Lattice.monoclinic(2, 9, 1, 99) elif sg_num in orthorhombic: lattice = Lattice.orthorhombic(2, 9, 1) elif sg_num in tetragonal: lattice = Lattice.tetragonal(2, 9) elif sg_num in rhombohedral: lattice = Lattice.hexagonal(2, 95) elif sg_num in hexagonal: lattice = Lattice.hexagonal(2, 9) elif sg_num in cubic: lattice = Lattice.cubic(2) struct = Structure.from_spacegroup(sg_num, lattice, species, coords) # Throws error if something doesn't work, causing test to fail. kpath = HighSymmKpath(struct, path_type="all") kpoints = kpath.get_kpoints()
def get_kpoints(self, structure): """ Get a KPOINTS file for NonSCF calculation. In "Line" mode, kpoints are generated along high symmetry lines. In "Uniform" mode, kpoints are Gamma-centered mesh grid. Kpoints are written explicitly in both cases. Args: structure (Structure/IStructure): structure to get Kpoints """ if self.mode == "Line": kpath = HighSymmKpath(structure) cart_k_points, k_points_labels = kpath.get_kpoints() frac_k_points = [kpath._prim_rec.get_fractional_coords(k) for k in cart_k_points] return Kpoints(comment="Non SCF run along symmetry lines", style="Reciprocal", num_kpts=len(frac_k_points), kpts=frac_k_points, labels=k_points_labels, kpts_weights=[1] * len(cart_k_points)) else: num_kpoints = self.kpoints_settings["kpoints_density"] * \ structure.lattice.reciprocal_lattice.volume kpoints = Kpoints.automatic_density( structure, num_kpoints * structure.num_sites) mesh = kpoints.kpts[0] ir_kpts = SymmetryFinder(structure, symprec=self.sym_prec) \ .get_ir_reciprocal_mesh(mesh) kpts = [] weights = [] for k in ir_kpts: kpts.append(k[0]) weights.append(int(k[1])) return Kpoints(comment="Non SCF run on uniform grid", style="Reciprocal", num_kpts=len(ir_kpts), kpts=kpts, kpts_weights=weights)
def get_line_mode_band_structure( self, line_density: int = 50, energy_cutoff: Optional[float] = None, scissor: Optional[float] = None, bandgap: Optional[float] = None, symprec: float = 0.01, ) -> BandStructureSymmLine: """Gets the interpolated band structure along high symmetry directions. Args: line_density: The maximum number of k-points between each two consecutive high-symmetry k-points energy_cutoff: The energy cut-off to determine which bands are included in the interpolation. If the energy of a band falls within the cut-off at any k-point it will be included. For metals the range is defined as the Fermi level ± energy_cutoff. For gapped materials, the energy range is from the VBM - energy_cutoff to the CBM + energy_cutoff. scissor: The amount by which the band gap is scissored. Cannot be used in conjunction with the ``bandgap`` option. Has no effect for metallic systems. bandgap: Automatically adjust the band gap to this value. Cannot be used in conjunction with the ``scissor`` option. Has no effect for metallic systems. symprec: The symmetry tolerance used to determine the space group and high-symmetry path. Returns: The line mode band structure. """ hsk = HighSymmKpath(self._band_structure.structure, symprec=symprec) kpoints, labels = hsk.get_kpoints(line_density=line_density, coords_are_cartesian=True) labels_dict = { label: kpoint for kpoint, label in zip(kpoints, labels) if label != "" } energies = self.get_energies( kpoints, scissor=scissor, bandgap=bandgap, atomic_units=False, energy_cutoff=energy_cutoff, coords_are_cartesian=True, ) return BandStructureSymmLine( kpoints, energies, self._band_structure.structure.lattice, self._band_structure.efermi, labels_dict, coords_are_cartesian=True, )
def get_band_structure(self, kpaths=None, kpoints_lbls_dict=None, density=20): """ Return a BandStructureSymmLine object interpolating bands along a High symmetry path calculated from the structure using HighSymmKpath function. If kpaths and kpoints_lbls_dict are provided, a custom path is interpolated. kpaths: List of lists of following kpoints labels defining the segments of the path. E.g. [['L','M'],['L','X']] kpoints_lbls_dict: Dict where keys are the kpoint labels used in kpaths and values are their fractional coordinates. E.g. {'L':np.array(0.5,0.5,0.5)}, 'M':np.array(0.5,0.,0.5), 'X':np.array(0.5,0.5,0.)} density: Number of points in each segment. """ if isinstance(kpaths, list) and isinstance(kpoints_lbls_dict, dict): kpoints = [] for kpath in kpaths: for i, k in enumerate(kpath[:-1]): sta = kpoints_lbls_dict[kpath[i]] end = kpoints_lbls_dict[kpath[i + 1]] kpoints.append(np.linspace(sta, end, density)) kpoints = np.concatenate(kpoints) else: kpath = HighSymmKpath(self.data.structure) kpoints = np.vstack( kpath.get_kpoints(density, coords_are_cartesian=False)[0]) kpoints_lbls_dict = kpath.kpath["kpoints"] lattvec = self.data.get_lattvec() egrid, vgrid = fite.getBands(kpoints, self.equivalences, lattvec, self.coeffs) # print(egrid.shape) if self.data.is_spin_polarized: h = sum(np.array_split(self.accepted, 2)[0]) egrid = np.array_split(egrid, [h], axis=0) bands_dict = { Spin.up: (egrid[0] / units.eV), Spin.down: (egrid[1] / units.eV), } else: bands_dict = {Spin.up: (egrid / units.eV)} sbs = BandStructureSymmLine( kpoints, bands_dict, self.data.structure.lattice.reciprocal_lattice, self.efermi / units.eV, labels_dict=kpoints_lbls_dict, ) return sbs
def get_phonon_band_structure_symm_line_from_fc( structure: Structure, supercell_matrix: np.ndarray, force_constants: np.ndarray, line_density: float = 20.0, symprec: float = 0.01, **kwargs, ) -> PhononBandStructureSymmLine: """ Get a phonon band structure along a high symmetry path from phonopy force constants. Args: structure: A structure. supercell_matrix: The supercell matrix used to generate the force constants. force_constants: The force constants in phonopy format. line_density: The density along the high symmetry path. symprec: Symmetry precision passed to phonopy and used for determining the band structure path. **kwargs: Additional kwargs passed to the Phonopy constructor. Returns: The line mode band structure. """ structure_phonopy = get_phonopy_structure(structure) phonon = Phonopy(structure_phonopy, supercell_matrix=supercell_matrix, symprec=symprec, **kwargs) phonon.set_force_constants(force_constants) kpath = HighSymmKpath(structure, symprec=symprec) kpoints, labels = kpath.get_kpoints(line_density=line_density, coords_are_cartesian=False) phonon.run_qpoints(kpoints) frequencies = phonon.qpoints.get_frequencies().T labels_dict = {a: k for a, k in zip(labels, kpoints) if a != ""} return PhononBandStructureSymmLine(kpoints, frequencies, structure.lattice, labels_dict=labels_dict)
def testKpoints(self): """ Kpointsをチェック """ # for Band src = os.path.join(self.path, 'src_poscar') poscar = vasp.Poscar.from_file(src, check_for_POTCAR=False) hsk = HighSymmKpath(poscar.structure) kpts = hsk.get_kpoints() args = {'comment': "Kpoints for band calc", 'kpts': kpts[0], 'num_kpts': len(kpts[0]), 'labels': kpts[1], 'style': 'Reciprocal', 'kpts_weights': [1]*len(kpts[0])} kpoints = vasp.Kpoints(**args) print(kpoints)
def get_kpoints(self, structure, kpoints_density=1000): """ Get a KPOINTS file for NonSCF calculation. In "Line" mode, kpoints are generated along high symmetry lines. In "Uniform" mode, kpoints are Gamma-centered mesh grid. Kpoints are written explicitly in both cases. Args: kpoints_density: kpoints density for the reciprocal cell of structure. Suggest to use a large kpoints_density. Might need to increase the default value when calculating metallic materials. """ if self.mode == "Line": kpath = HighSymmKpath(structure) cart_k_points, k_points_labels = kpath.get_kpoints() frac_k_points = [ kpath._prim_rec.get_fractional_coords(k) for k in cart_k_points ] return Kpoints(comment="Non SCF run along symmetry lines", style="Reciprocal", num_kpts=len(frac_k_points), kpts=frac_k_points, labels=k_points_labels, kpts_weights=[1] * len(cart_k_points)) else: num_kpoints = kpoints_density * \ structure.lattice.reciprocal_lattice.volume kpoints = Kpoints.automatic_density( structure, num_kpoints * structure.num_sites) mesh = kpoints.kpts[0] ir_kpts = SymmetryFinder(structure, symprec=0.01)\ .get_ir_reciprocal_mesh(mesh) kpts = [] weights = [] for k in ir_kpts: kpts.append(k[0]) weights.append(int(k[1])) return Kpoints(comment="Non SCF run on uniform grid", style="Reciprocal", num_kpts=len(ir_kpts), kpts=kpts, kpts_weights=weights)
def get_kpoints(self, structure, kpoints_density=1000): """ Get a KPOINTS file for NonSCF calculation. In "Line" mode, kpoints are generated along high symmetry lines. In "Uniform" mode, kpoints are Gamma-centered mesh grid. Kpoints are written explicitly in both cases. Args: kpoints_density: kpoints density for the reciprocal cell of structure. Suggest to use a large kpoints_density. Might need to increase the default value when calculating metallic materials. """ if self.mode == "Line": kpath = HighSymmKpath(structure) cart_k_points, k_points_labels = kpath.get_kpoints() frac_k_points = [kpath._prim_rec.get_fractional_coords(k) for k in cart_k_points] return Kpoints(comment="Non SCF run along symmetry lines", style="Reciprocal", num_kpts=len(frac_k_points), kpts=frac_k_points, labels=k_points_labels, kpts_weights=[1]*len(cart_k_points)) else: num_kpoints = kpoints_density * \ structure.lattice.reciprocal_lattice.volume kpoints = Kpoints.automatic_density( structure, num_kpoints * structure.num_sites) mesh = kpoints.kpts[0] ir_kpts = SymmetryFinder(structure, symprec=0.01)\ .get_ir_reciprocal_mesh(mesh) kpts = [] weights = [] for k in ir_kpts: kpts.append(k[0]) weights.append(int(k[1])) return Kpoints(comment="Non SCF run on uniform grid", style="Reciprocal", num_kpts=len(ir_kpts), kpts=kpts, kpts_weights=weights)
def smart_converge(mat=None,encut='',leng='',band_str=True,elast_prop=True,optical_prop=True,mbj_prop=True,spin_orb=False,phonon=False,surf_en=False,def_en=False): """ Main function to converge k-points/cut-off optimize structure, and run subsequent property calculations Args: mat: Poscar object with structure information encut: if '' then automataic convergence, else use defined fixed-cutoff leng: if '' then automataic convergence, else use defined fixed-line density band_str: if True then do band-structure calculations along high-symmetry points elast_prop: if True then do elastic property calculations using finite-difference optical_prop: if True do frequency dependent dielectric function calculations using he independent-particle (IP) approximation mbj_prop: if True do METAGGA-TBmBJ optical property calculations with IP approximation spin_orb: if True do spin-orbit calculations phonon: if True do phonon calculations using DFPT surf_en: if True do surface enrgy calculations def_en: if True do defect enrgy calculations Returns: en2: final energy mat_f: final structure """ if encut=="": encut=converg_encut(encut=500,mat=mat) if leng=="": leng= converg_kpoints(length=0,mat=mat) kpoints=Auto_Kpoints(mat=mat,length=leng) isif=2 commen=str(mat.comment) lcharg='.FALSE.' if commen.split('@')[0] =='bulk' : isif=3 lcharg='.TRUE.' if commen.split('@')[0] == 'sbulk': isif=3 incar_dict = use_incar_dict incar_dict.update({"ENCUT":encut,"EDIFFG":-1E-3,"ISIF":3,"NEDOS":5000,"NSW":500,"NELM":500,"LORBIT":11,"LVTOT":'.TRUE.',"LVHAR":'.TRUE.',"ISPIN":2,"LCHARG":'.TRUE.'}) incar = Incar.from_dict(incar_dict) try: if mat.comment.startswith('Mol'): incar.update({"ISIF": '2'}) except: print ("Mol error") pass #if commen.startswith('Surf-') : # pol=check_polar(mat_f.structure) # if pol==True: # ase_atoms = AseAtomsAdaptor().get_atoms(mat_f.structure) # COM=ase_atoms.get_center_of_mass(scaled=True) # incar.update({"LDIPOL": '.TRUE.',"IDIPOL":4,"ISYM": 0,"DIPOL":COM}) print ("running smart_converge for",str(mat.comment)+str('-')+str('MAIN-RELAX')) cwd=str(os.getcwd()) en2,contc=run_job(mat=mat,incar=incar,kpoints=kpoints,jobname=str('MAIN-RELAX')+str('-')+str(mat.comment)) os.chdir(cwd) path=str(contc.split('/CONTCAR')[0])+str('/vasprun.xml') v=open(path,"r").readlines() for line in v: if "NBANDS" in line: nbands=int(line.split(">")[1].split("<")[0]) print ("nbands=",nbands) break strt=Structure.from_file(contc) mat_f=Poscar(strt) mat_f.comment=str(mat.comment) if band_str==True: incar_dict = use_incar_dict incar_dict.update({"ISPIN":2,"NEDOS":5000,"LORBIT":11,"IBRION":1,"ENCUT":encut,"NBANDS":int(nbands)+10}) incar = Incar.from_dict(incar_dict) kpath = HighSymmKpath(mat_f.structure) frac_k_points, k_points_labels = kpath.get_kpoints(line_density=20,coords_are_cartesian=False) kpoints = Kpoints(comment="Non SCF run along symmetry lines",style=Kpoints.supported_modes.Reciprocal,num_kpts=len(frac_k_points),kpts=frac_k_points, labels=k_points_labels,kpts_weights=[1] * len(frac_k_points)) try: print ("running MAIN-BAND") kpoints=mpvis.get_kpoints(mat_f.structure) en2B,contcB=run_job(mat=mat_f,incar=incar,kpoints=kpoints,jobname=str('MAIN-BAND')+str('-')+str(mat_f.comment)) # kpoints=mpvis.get_kpoints(mat_f.structure) # en2B,contcB=run_job(mat=mat_f,incar=incar,kpoints=kpoints,jobname=str('MAIN-BAND')+str('-')+str(mat_f.comment)) except: print ("No band str calc.") if str(os.getcwd)!=cwd: print ("Changing directory") line=str("cd ")+str(cwd) os.chdir(cwd) print (os.getcwd()) pass os.chdir(cwd) if surf_en==True: incar_dict = use_incar_dict incar_dict.update({"ENCUT":encut,"NEDOS":5000,"IBRION":1,"NSW":500,"LORBIT":11}) incar = Incar.from_dict(incar_dict) surf=surfer(mat=mat_f.structure,layers=3) for i in surf: try: print ("running MAIN-BAND") #NSCF #chg_file=str(contc).replace('CONTCAR','CHGCAR') #print ('chrfile',chg_file) #shutil.copy2(chg_file,'./') kpoints=Auto_Kpoints(mat=i,length=leng) en2s,contcs=run_job(mat=i,incar=incar,kpoints=kpoints,jobname=str('Surf_en-')+str(i.comment)+str('-')+str(mat_f.comment)) #kpoints=mpvis.get_kpoints(mat_f.structure) #en2B,contcB=run_job(mat=mat_f,incar=incar,kpoints=kpoints,jobname=str('MAIN-BAND')+str('-')+str(mat_f.comment)) except: pass os.chdir(cwd) if def_en==True: incar_dict = use_incar_dict incar_dict.update({"ENCUT":encut,"NEDOS":5000,"IBRION":1,"NSW":500,"LORBIT":11}) incar = Incar.from_dict(incar_dict) #surf=surfer(mat=mat_f.structure,layers=3) vac=vac_antisite_def_struct_gen(cellmax=3,struct=mat_f.structure) for i in vac: try: print ("running MAIN-vac") kpoints=Auto_Kpoints(mat=i,length=leng) en2d,contcd=run_job(mat=i,incar=incar,kpoints=kpoints,jobname=str('Def_en-')+str(i.comment)+str('-')+str(mat_f.comment)) # kpoints=mpvis.get_kpoints(mat_f.structure) # en2B,contcB=run_job(mat=mat_f,incar=incar,kpoints=kpoints,jobname=str('MAIN-BAND')+str('-')+str(mat_f.comment)) except: pass os.chdir(cwd) #surf=surfer(mat=strt,layers=layers) #surf=surfer(mat=strt,layers=layers) if spin_orb==True: #chg_file=str(contc).replace('CONTCAR','CHGCAR') #print ('chrfile',chg_file) #shutil.copy2(chg_file,'./') incar_dict = use_incar_dict incar_dict.update({"ENCUT":encut,"NPAR":ncores,"GGA_COMPAT":'.FALSE.',"LSORBIT":'.TRUE.',"IBRION":1,"ISYM":0,"NEDOS":5000,"IBRION":1,"NSW":500,"LORBIT":11}) incar = Incar.from_dict(incar_dict) sg_mat = SpacegroupAnalyzer(mat_f.structure) mat_cvn = sg_mat.get_conventional_standard_structure() mat_cvn.sort() kpoints=Auto_Kpoints(mat=Poscar(mat_cvn),length=leng/2) try: en2S,contcS=run_job(mat=Poscar(mat_cvn),incar=incar,kpoints=kpoints,jobname=str('MAIN-SOC')+str('-')+str(mat_f.comment)) except: pass os.chdir(cwd) if optical_prop==True: incar_dict = use_incar_dict incar_dict.update({"NEDOS":5000,"LORBIT":11,"IBRION":1,"ENCUT":encut,"NBANDS":3*int(nbands),"LOPTICS":'.TRUE.'}) incar = Incar.from_dict(incar_dict) kpoints=Auto_Kpoints(mat=mat_f,length=leng) try: en2OP,contcOP=run_job(mat=mat_f,incar=incar,kpoints=kpoints,jobname=str('MAIN-OPTICS')+str('-')+str(mat_f.comment)) except: pass os.chdir(cwd) if mbj_prop==True: incar_dict = use_incar_dict incar_dict.update({"NEDOS":5000,"LORBIT":11,"IBRION":1,"ENCUT":encut,"NBANDS":3*int(nbands),"LOPTICS":'.TRUE.','METAGGA':'MBJ','ISYM':0,"SIGMA":0.1}) incar = Incar.from_dict(incar_dict) kpoints=Auto_Kpoints(mat=mat_f,length=leng) try: en2OP,contcOP=run_job(mat=mat_f,incar=incar,kpoints=kpoints,jobname=str('MAIN-MBJ')+str('-')+str(mat_f.comment)) except: pass os.chdir(cwd) if elast_prop==True: incar_dict = use_incar_dict incar_dict.update({"NEDOS":5000,"IBRION":6,"ENCUT":1.3*float(encut),"ISIF":3,"POTIM":0.015,"NPAR":ncores,"ISPIN":2}) incar = Incar.from_dict(incar_dict) sg_mat = SpacegroupAnalyzer(mat_f.structure) mat_cvn = sg_mat.get_conventional_standard_structure() mat_cvn.sort() kpoints=Auto_Kpoints(mat=Poscar(mat_cvn),length=leng) try: en2E,contcE=run_job(mat=Poscar(mat_cvn),incar=incar,kpoints=kpoints,jobname=str('MAIN-ELASTIC')+str('-')+str(mat_f.comment)) except: pass os.chdir(cwd) if phonon==True: incar_dict = use_incar_dict incar_dict.update({"IBRION":8,"ENCUT":float(encut),"ISYM":0,"ADDGRID":'.TRUE.','EDIFF': 1e-09,'LORBIT': 11}) incar = Incar.from_dict(incar_dict) kpoints=Auto_Kpoints(mat=mat_f,length=leng) mat_pho=make_big(poscar=mat_f,size=11.0) try: en2P,contcP=run_job(mat=mat_pho,incar=incar,kpoints=kpoints,jobname=str('MAIN-PHO8')+str('-')+str(mat_f.comment)) except: pass os.chdir(cwd) #if Raman_calc==True: # Raman(strt=mat_f,encut=encut,length=leng) os.chdir(cwd) return en2,mat_f
def main(): """ Main routine """ parser = argparse.ArgumentParser(description='Calculate the band structure of a vasp calculation.') parser.add_argument('-d', '--density', nargs='?', default=10, type=int, help='k-point density of the bands (default: 10)') parser.add_argument('-s', '--sigma', nargs='?', default=0.04, type=float, help='SIGMA value in eV (default: 0.04)') parser.add_argument('-l', '--linemode', nargs='?', default=None, type=str, help='linemode file') parser.add_argument('-v', '--vasp', nargs='?', default='vasp', type=str, help='vasp executable') args = parser.parse_args() line_density = args.density line_file = args.linemode # Check that required files exist _check('vasprun.xml') _check('INCAR') _check('POSCAR') _check('POTCAR') _check('CHGCAR') # Get IBZ from vasprun vasprun = Vasprun('vasprun.xml') ibz = HighSymmKpath(vasprun.final_structure) # Create a temp directory print('Create temporary directory ... ', end='') tempdir = mkdtemp() print(tempdir) # Edit the inputs print('Saving new inputs in temporary directory ... ') incar = Incar.from_file('INCAR') print('Making the following changes to the INCAR:') print(' ICHARG = 11') print(' ISMEAR = 0') print(' SIGMA = %f' % args.sigma) incar['ICHARG'] = 11 # Constant density incar['ISMEAR'] = 0 # Gaussian Smearing incar['SIGMA'] = args.sigma # Smearing temperature incar.write_file(os.path.join(tempdir, 'INCAR')) # Generate line-mode kpoint file if line_file is None: print('Creating a new KPOINTS file:') kpoints = _automatic_kpoints(line_density, ibz) kpoints.write_file(os.path.join(tempdir, 'KPOINTS')) print('### BEGIN KPOINTS') print(kpoints) print('### END KPOINTS') else: cp(line_file, os.path.join(tempdir, 'KPOINTS')) # Copy other files (May take some time...) print('Copying POSCAR, POTCAR and CHGCAR to the temporary directory.') cp('POSCAR', os.path.join(tempdir, 'POSCAR')) cp('POTCAR', os.path.join(tempdir, 'POTCAR')) cp('CHGCAR', os.path.join(tempdir, 'CHGCAR')) # cd to temp directory and run vasp path = os.getcwd() os.chdir(tempdir) print('Running VASP in the temporary directory ...') try: check_call(args.vasp) except CalledProcessError: print('There was an error running VASP') _clean_exit(path, tempdir) # Read output vasprun = Vasprun('vasprun.xml') ibz = HighSymmKpath(vasprun.final_structure) _, _ = ibz.get_kpoints(line_density) bands = vasprun.get_band_structure() print('Success! Efermi = %f' % bands.efermi) # Backup vasprun.xml only print('Making a gzip backup of vasprun.xml called bands_vasprun.xml.gz') zfile = os.path.join(path, 'bands_vasprun.xml.gz') try: with gzip.open(zfile, 'wb') as gz, open('vasprun.xml', 'rb') as vr: gz.writelines(vr) except (OSError, IOError): print('There was an error with gzip') _clean_exit(path, tempdir) # Return to original path os.chdir(path) # Write band structure # There may be multiple bands due to spin or noncollinear. for key, item in bands.bands.items(): print('Preparing bands_%s.csv' % key) kpts = [] # Get list of kpoints for kpt in bands.kpoints: kpts.append(kpt.cart_coords) # Subtract fermi energy print('Shifting energies so Efermi = 0.') band = numpy.array(item) - bands.efermi # Prepend kpoint vector as label out = numpy.hstack([kpts, band.T]) final = [] lastrow = float('inf') * numpy.ones(3) for row in out: if numpy.linalg.norm(row[:3] - lastrow) > 1.e-12: final.append(row) lastrow = row[:3] # Write bands to csv file. print('Writing bands_%s.csv to disk' % key) with open('bands_%s.csv' % key, 'w+') as f: numpy.savetxt(f, numpy.array(final), delimiter=',', header=' kptx, kpty, kptz, band1, band2, ... ') # Delete temporary directory _clean_exit(path, tempdir, 0)
def get_anaddb_input(self, item): """ creates the AnaddbInput object. It also returns the list of qpoints labels for generating the PhononBandStructureSymmLine. """ ngqpt = item["abinit_input.ngqpt"] q1shft = [(0, 0, 0)] structure = Structure.from_dict(item["abinit_input.structure"]) hs = HighSymmKpath(structure, symprec=1e-2) spgn = hs._sym.get_space_group_number() if spgn != item["spacegroup.number"]: raise RuntimeError("Parsed specegroup number {} does not match " "calculation spacegroup {}".format(spgn, item["spacegroup.number"])) # for the moment use gaussian smearing prtdos = 1 dossmear = 3 / Ha_cmm1 lo_to_splitting = True dipdip = 1 asr = 2 chneut = 1 ng2qppa = 50000 inp = AnaddbInput(structure, comment="ANADB input for phonon bands and DOS") inp.set_vars( ifcflag=1, ngqpt=np.array(ngqpt), q1shft=q1shft, nqshft=len(q1shft), asr=asr, chneut=chneut, dipdip=dipdip, ) # Parameters for the dos. ng2qpt = KSampling.automatic_density(structure, kppa=ng2qppa).kpts[0] inp.set_vars(prtdos=prtdos, dosdeltae=None, dossmear=dossmear, ng2qpt=ng2qpt) # Parameters for the BS qpts, labels_list = hs.get_kpoints(line_density=18, coords_are_cartesian=False) n_qpoints = len(qpts) qph1l = np.zeros((n_qpoints, 4)) qph1l[:, :-1] = qpts qph1l[:, -1] = 1 inp['qph1l'] = qph1l.tolist() inp['nph1l'] = n_qpoints if lo_to_splitting: kpath = hs.kpath directions = [] for qptbounds in kpath['path']: for i, qpt in enumerate(qptbounds): if np.array_equal(kpath['kpoints'][qpt], (0, 0, 0)): # anaddb expects cartesian coordinates for the qph2l list if i > 0: directions.extend(structure.lattice.reciprocal_lattice_crystallographic.get_cartesian_coords( kpath['kpoints'][qptbounds[i - 1]])) directions.append(0) if i < len(qptbounds) - 1: directions.extend(structure.lattice.reciprocal_lattice_crystallographic.get_cartesian_coords( kpath['kpoints'][qptbounds[i + 1]])) directions.append(0) if directions: directions = np.reshape(directions, (-1, 4)) inp.set_vars( nph2l=len(directions), qph2l=directions ) return inp, labels_list
def get_bs_extrema(bs, coeff_file=None, interp_params=None, method="boltztrap1", line_density=30, min_normdiff=4.0, Ecut=None, eref=None, return_global=False, n_jobs=-1, nbelow_vbm=0, nabove_cbm=0, scissor=0.0): """ Returns a dictionary of p-type (valence) and n-type (conduction) band extrema k-points by looking at the 1st and 2nd derivatives of the bands Args: bs (pymatgen BandStructure object): must contain Structure and have the same number of valence electrons and settings as the vasprun.xml from which coeff_file is generated. coeff_file (str): path to the cube file from BoltzTraP run line_density (int): maximum number of k-points between each two consecutive high-symmetry k-points v_cut (float): threshold under which the derivative is assumed 0 [cm/s] min_normdiff (float): the minimum allowed distance norm(cartesian k in 1/nm) in extrema; this is important to avoid numerical instability errors or finding peaks that are too close to each other for Amset formulation to be relevant. Ecut (float or dict): max energy difference with CBM/VBM allowed for extrema. Valid examples: 0.25 or {'n': 0.5, 'p': 0.25} , ... eref (dict): BandStructure global VBM/CBM used as a global reference energy for Ecut. Example: {'n': 6.0, 'p': 5.0}. Ignored if None in which case maximum/minimum of the current valence/conduction used return_global (bool): in addition to the extrema, return the actual CBM (global minimum) and VBM (global maximum) w/ their k-point n_jobs (int): number of processors used in boltztrap1 interpolation nbelow_vbm (int): # of bands below the last valence band nabove_vbm (int): # of bands above the first conduction band scissor (float): the amount by which the band gap is altered/scissored. Returns (dict): {'n': list of extrema fractional coordinates, 'p': same} """ lattice_matrix = bs.structure.lattice.reciprocal_lattice.matrix def to_cart(k): """ convert fractional k-points to cartesian coordinates in (1/nm) units """ return np.dot(lattice_matrix, k) * 10. Ecut = Ecut or 10 * k_B * 300 if not isinstance(Ecut, dict): Ecut = {'n': Ecut, 'p': Ecut} if eref is None: global_extrema = {'n': {}, 'p': {}} else: cbmk = np.array(bs.get_cbm()['kpoint'].frac_coords) vbmk = np.array(bs.get_vbm()['kpoint'].frac_coords) global_extrema = { 'n': { 'energy': eref['n'], 'kpoint': cbmk }, 'p': { 'energy': eref['p'], 'kpoint': vbmk } } final_extrema = {'n': [], 'p': []} hsk = HighSymmKpath(bs.structure) hs_kpoints, _ = hsk.get_kpoints(line_density=line_density) hs_kpoints = kpts_to_first_BZ(hs_kpoints) vbm_idx, _ = get_bindex_bspin(bs.get_vbm(), is_cbm=False) cbm_idx, _ = get_bindex_bspin(bs.get_cbm(), is_cbm=True) if method == "boltztrap1" and interp_params is None: interp_params = get_energy_args( coeff_file=coeff_file, ibands=[vbm_idx + 1 - nbelow_vbm, cbm_idx + 1 + nabove_cbm]) for ip, tp in enumerate(["p", "n"]): # hence iband == 0 or 1 if method == "boltztrap1": iband = ip else: iband = ip * (cbm_idx + nabove_cbm) + (1 - ip) * (vbm_idx - nbelow_vbm) + 1 band, _, _ = interpolate_bs(hs_kpoints, interp_params, iband=iband, method=method, scissor=scissor, matrix=bs.structure.lattice.matrix, n_jobs=n_jobs, sgn=(-1)**ip) global_ext_idx = (1 - iband) * np.argmax(band) + iband * np.argmin(band) if eref is None: global_extrema[tp]['energy'] = band[global_ext_idx] global_extrema[tp]['kpoint'] = hs_kpoints[global_ext_idx] extrema_idx = detect_peaks(band, mph=None, mpd=1, valley=ip == 1) # making sure CBM & VBM are always included regardless of min_normdiff extrema_energies = [band[i] for i in extrema_idx] sorted_idx = np.argsort(extrema_energies) if tp == 'p': sorted_idx = sorted_idx[::-1] extrema_idx = extrema_idx[sorted_idx] extrema_init = [] for idx in extrema_idx: k_localext = hs_kpoints[idx] if abs(band[idx] - global_extrema[tp]['energy']) < Ecut[tp]: far_enough = True for kp in extrema_init: kp = np.array(kp) if norm( to_cart( get_closest_k( k_localext, np.vstack((bs.get_sym_eq_kpoints(-kp), bs.get_sym_eq_kpoints(kp))), return_diff=True))) <= min_normdiff: far_enough = False if far_enough: extrema_init.append(k_localext) # check to see if one of the actual high-symm k-points can be used hisymks = list(hsk.kpath['kpoints'].values()) all_hisymks = [] for kp in hisymks: all_hisymks += list( np.vstack( (bs.get_sym_eq_kpoints(-kp), bs.get_sym_eq_kpoints(kp)))) for k_ext_found in extrema_init: kp = get_closest_k(k_ext_found, all_hisymks, return_diff=False) if norm(to_cart(kp - k_ext_found)) < min_normdiff / 10.0: final_extrema[tp].append(kp) else: final_extrema[tp].append(k_ext_found) # sort the extrema based on their energy (i.e. importance) subband, _, _ = interpolate_bs(final_extrema[tp], interp_params, iband=iband, method=method, scissor=scissor, matrix=bs.structure.lattice.matrix, n_jobs=n_jobs, sgn=(-1)**ip) sorted_idx = np.argsort(subband) if iband == 0: sorted_idx = sorted_idx[::-1] final_extrema[tp] = [final_extrema[tp][i] for i in sorted_idx] if return_global: return final_extrema, global_extrema else: return final_extrema
print("File %s does not exist" % fstruct) exit(1) # symmetry information struct_sym = SpacegroupAnalyzer(struct) print("\nLattice details:") print("----------------") print("lattice type : {0}".format(struct_sym.get_lattice_type())) print("space group : {0} ({1})".format(struct_sym.get_space_group_symbol(), struct_sym.get_space_group_number())) # Compute first brillouin zone ibz = HighSymmKpath(struct) print("ibz type : {0}".format(ibz.name)) # get_kpath_plot(savefig="path.png") [x, y, z] = list(map(list, zip(*ibz.get_kpoints()[0]))) fig = plt.figure() ax = fig.gca(projection='3d') ax.plot(x, y, z) plt.show(block=False) # print specific kpoints in the first brillouin zone print("\nList of high symmetry k-points:") print("-------------------------------") for key, val in ibz.kpath["kpoints"].items(): print("%8s %s" % (key, str(val))) # suggested path for the band structure print("\nSuggested paths in first brillouin zone:") print("----------------------------------------") for i, path in enumerate(ibz.kpath["path"]):
def drawkpt(struct, ndiv="10"): # symmetry information struct_sym = SpacegroupAnalyzer(struct) print("\nLattice details:") print("----------------") print("lattice type : {0}".format(struct_sym.get_lattice_type())) print( "space group : {0} ({1})".format( struct_sym.get_space_group_symbol(), struct_sym.get_space_group_number())) # Compute first brillouin zone ibz = HighSymmKpath(struct) print("ibz type : {0}".format(ibz.name)) [x, y, z] = list(map(list, zip(*ibz.get_kpoints()[0]))) fig = plt.figure("Brillouin Zone and High Symm Pts") ax = fig.gca(projection='3d') ax.plot(x, y, z) for i, name in enumerate(ibz.get_kpoints()[1]): if name != '': #print(" name {0} : [{1},{2},{3}]".format(name, x[i],y[i],z[i])) ax.text(x[i], y[i], z[i], '%s' % (name), color='k', size="15") new_lat = ibz.prim_rec bz_array = new_lat.get_wigner_seitz_cell() bz_faces = Poly3DCollection(bz_array) bz_faces.set_edgecolor('k') bz_faces.set_facecolor((0, 1, 1, 0.4)) ax.add_collection3d(bz_faces) ax.set_xlim(-1, 1) ax.set_ylim(-1, 1) ax.set_zlim(-1, 1) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') fig.suptitle( "Brillouin Zone and K_Path of \n {0}".format( struct.get_primitive_structure().formula)) fig.show() # if input("press [s]ave to save brillouin zone figure as it is \n") == "s": # fig.savefig("BZ_KPath.svg", bbox_inches='tight') # plt.close(fig) # print specific kpoints in the first brillouin zone print("\nList of high symmetry k-points:") print("-------------------------------") for key, val in ibz.kpath["kpoints"].items(): print("%8s %s" % (key, str(val))) # suggested path for the band structure print("\nSuggested paths in first brillouin zone:") print("----------------------------------------") for i, path in enumerate(ibz.kpath["path"]): print(" %2d:" % (i + 1), " -> ".join(path)) # write the KPOINTS file print("\nWrite file KPOINTS") kpt = Kpoints.automatic_linemode(ndiv, ibz) # if input("write kpt in cwd ?") == "Y": # kpt.write_file(os.path.join( # folder, "linear_KPOINTS")) return(kpt)
def write_KPOINTS( POSCAR_input: str = "POSCAR", KPOINTS_output="KPOINTS.lobster", reciprocal_density: int = 100, isym: int = -1, from_grid: bool = False, input_grid: list = [5, 5, 5], line_mode: bool = True, kpoints_line_density: int = 20, symprec: float = 0.01, ): """ writes a KPOINT file for lobster (only ISYM=-1 and ISYM=0 are possible), grids are gamma centered Args: POSCAR_input (str): path to POSCAR KPOINTS_output (str): path to output KPOINTS reciprocal_density (int): Grid density isym (int): either -1 or 0. Current Lobster versions only allow -1. from_grid (bool): If True KPOINTS will be generated with the help of a grid given in input_grid. Otherwise, they will be generated from the reciprocal_density input_grid (list): grid to generate the KPOINTS file line_mode (bool): If True, band structure will be generated kpoints_line_density (int): density of the lines in the band structure symprec (float): precision to determine symmetry """ structure = Structure.from_file(POSCAR_input) if not from_grid: kpointgrid = Kpoints.automatic_density_by_vol( structure, reciprocal_density).kpts mesh = kpointgrid[0] else: mesh = input_grid # The following code is taken from: SpacegroupAnalyzer # we need to switch off symmetry here latt = structure.lattice.matrix positions = structure.frac_coords unique_species = [] # type: List[Any] zs = [] magmoms = [] for species, g in itertools.groupby(structure, key=lambda s: s.species): if species in unique_species: ind = unique_species.index(species) zs.extend([ind + 1] * len(tuple(g))) else: unique_species.append(species) zs.extend([len(unique_species)] * len(tuple(g))) for site in structure: if hasattr(site, "magmom"): magmoms.append(site.magmom) elif site.is_ordered and hasattr(site.specie, "spin"): magmoms.append(site.specie.spin) else: magmoms.append(0) # For now, we are setting magmom to zero. (Taken from INCAR class) cell = latt, positions, zs, magmoms # TODO: what about this shift? mapping, grid = spglib.get_ir_reciprocal_mesh(mesh, cell, is_shift=[0, 0, 0]) # exit() # get the kpoints for the grid if isym == -1: kpts = [] weights = [] all_labels = [] for gp in grid: kpts.append(gp.astype(float) / mesh) weights.append(float(1)) all_labels.append("") elif isym == 0: # time reversal symmetry: k and -k are equivalent kpts = [] weights = [] all_labels = [] newlist = [list(gp) for gp in list(grid)] mapping = [] for gp in newlist: minus_gp = [-k for k in gp] if minus_gp in newlist and minus_gp not in [[0, 0, 0]]: mapping.append(newlist.index(minus_gp)) else: mapping.append(newlist.index(gp)) for igp, gp in enumerate(newlist): if mapping[igp] > igp: kpts.append(np.array(gp).astype(float) / mesh) weights.append(float(2)) all_labels.append("") elif mapping[igp] == igp: kpts.append(np.array(gp).astype(float) / mesh) weights.append(float(1)) all_labels.append("") else: ValueError("Only isym=-1 and isym=0 are allowed.") # line mode if line_mode: kpath = HighSymmKpath(structure, symprec=symprec) if not np.allclose(kpath.prim.lattice.matrix, structure.lattice.matrix): raise ValueError( "You are not using the standard primitive cell. The k-path is not correct. Please generate a " "standard primitive cell first.") frac_k_points, labels = kpath.get_kpoints( line_density=kpoints_line_density, coords_are_cartesian=False) for k, f in enumerate(frac_k_points): kpts.append(f) weights.append(0.0) all_labels.append(labels[k]) if isym == -1: comment = ("ISYM=-1, grid: " + str(mesh) if not line_mode else "ISYM=-1, grid: " + str(mesh) + " plus kpoint path") elif isym == 0: comment = ("ISYM=0, grid: " + str(mesh) if not line_mode else "ISYM=0, grid: " + str(mesh) + " plus kpoint path") KpointObject = Kpoints( comment=comment, style=Kpoints.supported_modes.Reciprocal, num_kpts=len(kpts), kpts=kpts, kpts_weights=weights, labels=all_labels, ) KpointObject.write_file(filename=KPOINTS_output)
amset = Amset(calc_dir='.', material_params={'epsilon_s': 12.9}, temperatures=temperatures, dopings=dopings, performance_params={'Ecut': 1.0} ) amset.read_vrun(vasprun_file=vrun_file) amset.update_cbm_vbm_dos(coeff_file) extrema = amset.find_all_important_points(coeff_file, nbelow_vbm=0, nabove_cbm=0, interpolation="boltztrap1", line_density=LINE_DENSITY ) hsk = HighSymmKpath(vrun.final_structure) hs_kpoints , _ = hsk.get_kpoints(line_density=LINE_DENSITY) hs_kpoints = kpts_to_first_BZ(hs_kpoints) bs = vrun.get_band_structure() bsd = {} bsd['kpoints'] = hs_kpoints hs_kpoints = np.array(hs_kpoints) bsd['str_kpts'] = [str(k) for k in bsd['kpoints']] bsd['cartesian kpoints (1/nm)'] = [amset.get_cartesian_coords(k)/A_to_nm for k in bsd['kpoints']] bsd['normk'] = np.linalg.norm(bsd['cartesian kpoints (1/nm)'], axis=1) cbm_idx, cbm_spin = get_bindex_bspin(bs.get_cbm(), is_cbm=True) vbmd = bs.get_vbm() vbm_idx, vbm_spin = get_bindex_bspin(vbmd, is_cbm=False) vbm = vbmd['energy']