def process_vasprun(self, dir_name, taskname, filename): """ Adapted from matgendb.creator Process a vasprun.xml file. """ vasprun_file = os.path.join(dir_name, filename) if self.bandstructure_mode: vrun = Vasprun(vasprun_file, parse_eigen=True, parse_projected_eigen=True) else: vrun = Vasprun(vasprun_file) d = vrun.as_dict() for k, v in {"formula_pretty": "pretty_formula", "composition_reduced": "reduced_cell_formula", "composition_unit_cell": "unit_cell_formula"}.items(): d[k] = d.pop(v) for k in ["eigenvalues", "projected_eigenvalues"]: # large storage space breaks some docs if k in d["output"]: del d["output"][k] comp = Composition(d["composition_unit_cell"]) d["formula_anonymous"] = comp.anonymized_formula d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula d["dir_name"] = os.path.abspath(dir_name) d["completed_at"] = str(datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file))) d["density"] = vrun.final_structure.density # replace 'crystal' with 'structure' d["input"]["structure"] = d["input"].pop("crystal") d["output"]["structure"] = d["output"].pop("crystal") for k, v in {"energy": "final_energy", "energy_per_atom": "final_energy_per_atom"}.items(): d["output"][k] = d["output"].pop(v) if self.parse_dos and self.parse_dos != 'final': try: d["dos"] = vrun.complete_dos.as_dict() except: raise ValueError("No valid dos data exist in {}.".format(dir_name)) if self.bandstructure_mode: bs = vrun.get_band_structure(line_mode=(self.bandstructure_mode == "line")) else: bs = vrun.get_band_structure() d["bandstructure"] = bs.as_dict() d["output"]["vbm"] = bs.get_vbm()["energy"] d["output"]["cbm"] = bs.get_cbm()["energy"] bs_gap = bs.get_band_gap() d["output"]["bandgap"] = bs_gap["energy"] d["output"]["is_gap_direct"] = bs_gap["direct"] d["output"]["is_metal"] = bs.is_metal() d["task"] = {"type": taskname, "name": taskname} # phonon-dfpt if hasattr(vrun, "force_constants"): d["output"]["force_constants"] = vrun.force_constants.tolist() d["output"]["normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist() d["output"]["normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist() return d
def test_methods(self): v = Vasprun(os.path.join(test_dir, "vasprun_Si_bands.xml")) p = BSDOSPlotter() plt = p.get_plot(v.get_band_structure( kpoints_filename=os.path.join(test_dir, "KPOINTS_Si_bands"))) plt = p.get_plot(v.get_band_structure( kpoints_filename=os.path.join(test_dir, "KPOINTS_Si_bands")), v.complete_dos)
def test_methods(self): v = Vasprun(os.path.join(test_dir, "vasprun_Si_bands.xml")) p = BSDOSPlotter() plt = p.get_plot(v.get_band_structure( kpoints_filename=os.path.join(test_dir, "KPOINTS_Si_bands"))) plt = p.get_plot(v.get_band_structure( kpoints_filename=os.path.join(test_dir, "KPOINTS_Si_bands")), v.complete_dos)
def test_methods(self): v = Vasprun( os.path.join(PymatgenTest.TEST_FILES_DIR, "vasprun_Si_bands.xml")) p = BSDOSPlotter() plt = p.get_plot( v.get_band_structure(kpoints_filename=os.path.join( PymatgenTest.TEST_FILES_DIR, "KPOINTS_Si_bands"))) plt.close() plt = p.get_plot( v.get_band_structure(kpoints_filename=os.path.join( PymatgenTest.TEST_FILES_DIR, "KPOINTS_Si_bands")), v.complete_dos, ) plt.close("all")
def run_task(self, fw_spec): vr_path = zpath(self.get("vasprun_path", "vasprun.xml")) min_gap = self.get("min_gap", None) max_gap = self.get("max_gap", None) if not os.path.exists(vr_path): relax_paths = sorted(glob.glob(vr_path + ".relax*")) if relax_paths: if len(relax_paths) > 9: raise ValueError( "CheckBandgap doesn't properly handle >9 relaxations!") vr_path = relax_paths[-1] logger.info("Checking the gap of file: {}".format(vr_path)) vr = Vasprun(vr_path) gap = vr.get_band_structure().get_band_gap()["energy"] stored_data = {"band_gap": gap} logger.info("The gap is: {}. Min gap: {}. Max gap: {}".format( gap, min_gap, max_gap)) if (min_gap and gap < min_gap) or (max_gap and gap > max_gap): logger.info("CheckBandgap: failed test!") return FWAction(stored_data=stored_data, exit=True, defuse_workflow=True) return FWAction(stored_data=stored_data)
def run_task(self, fw_spec): vr_path = self.get("vasprun_path", "vasprun.xml") min_gap = self.get("min_gap", None) max_gap = self.get("max_gap", None) vr_path = zpath(vr_path) if not os.path.exists(vr_path): relax_paths = sorted(glob.glob(vr_path + ".relax*"), reverse=True) if relax_paths: if len(relax_paths) > 9: raise ValueError( "CheckBandgap doesn't properly handle >9 relaxations!") vr_path = relax_paths[0] print("Checking the gap of file: {}".format(vr_path)) vr = Vasprun(vr_path) gap = vr.get_band_structure().get_band_gap()["energy"] stored_data = {"band_gap": gap} print("The gap is: {}. Min gap: {}. Max gap: {}".format( gap, min_gap, max_gap)) if min_gap and gap < min_gap or max_gap and gap > max_gap: print("Defusing based on band gap!") return FWAction(stored_data=stored_data, exit=True, defuse_workflow=True) print("Gap OK...") return FWAction(stored_data=stored_data)
def run_task(self, fw_spec): vr_path = self.get("vasprun_path", "vasprun.xml") min_gap = self.get("min_gap", None) max_gap = self.get("max_gap", None) vr_path = zpath(vr_path) if not os.path.exists(vr_path): relax_paths = sorted(glob.glob(vr_path + ".relax*"), reverse=True) if relax_paths: if len(relax_paths) > 9: raise ValueError( "CheckBandgap doesn't properly handle >9 relaxations!") vr_path = relax_paths[0] print("Checking the gap of file: {}".format(vr_path)) vr = Vasprun(vr_path) gap = vr.get_band_structure().get_band_gap()["energy"] stored_data = {"band_gap": gap} print("The gap is: {}. Min gap: {}. Max gap: {}".format(gap, min_gap, max_gap)) if min_gap and gap < min_gap or max_gap and gap > max_gap: print("Defusing based on band gap!") return FWAction(stored_data=stored_data, exit=True, defuse_workflow=True) print("Gap OK...") return FWAction(stored_data=stored_data)
def run_task(self, fw_spec): vr_path = zpath(self.get("vasprun_path", "vasprun.xml")) min_gap = self.get("min_gap", None) max_gap = self.get("max_gap", None) if not os.path.exists(vr_path): relax_paths = sorted(glob.glob(vr_path + ".relax*")) if relax_paths: if len(relax_paths) > 9: raise ValueError( "CheckBandgap doesn't properly handle >9 relaxations!") vr_path = relax_paths[-1] logger.info("Checking the gap of file: {}".format(vr_path)) vr = Vasprun(vr_path) gap = vr.get_band_structure().get_band_gap()["energy"] stored_data = {"band_gap": gap} logger.info( "The gap is: {}. Min gap: {}. Max gap: {}".format(gap, min_gap, max_gap)) if (min_gap and gap < min_gap) or (max_gap and gap > max_gap): logger.info("CheckBandgap: failed test!") return FWAction(stored_data=stored_data, exit=True, defuse_workflow=True) return FWAction(stored_data=stored_data)
def get_bandgap_from_aexx(self, structure, aexx, outdir=None, previous=None): vasprun_location = os.path.join(outdir, str(aexx).zfill(2), self.names[-1], 'vasprun.xml') # try: # vasprun = Vasprun(vasprun_location, parse_projected_eigen=False) # band_gap = vasprun.get_band_structure().get_band_gap()['energy'] # except: def set_aexx(vasp: Vasp, structure=None): vasp.add_keyword('aexx', aexx / 100) return vasp for x in self.functionals: # Set nupdown x.modifications.append(set_aexx) (_, output) = super().call_with_output(structure, outdir=os.path.join( outdir, str(aexx).zfill(2)), previous=previous) vasprun = Vasprun(vasprun_location, parse_projected_eigen=False) band_gap = vasprun.get_band_structure().get_band_gap()['energy'] return (band_gap, output)
def spin_boltz(vrunfile="", spin=1, k_latt=1.0, write_json=True): fname = vrunfile.replace("vasprun.xml", "boltz2data.json") if not os.path.isfile(fname): kp = vrunfile.replace("vasprun.xml", "KPOINTS") v = Vasprun(vrunfile) nelect = v.parameters["NELECT"] bs = v.get_band_structure(kp, line_mode=False) # doping=10.**np.arange(20,22) temp_r = np.array([300, 400, 500, 600, 700, 800]) doping = np.array([0, 10**18, 10**19, 10**20, 10**21, 10**22]) loader = BandstructureLoader(bs, v.structures[-1], spin=spin, nelect=nelect) bztInterp = BztInterpolator(loader, lpfac=2, curvature=True) bztTransp = BztTransportProperties(bztInterp, doping=doping, temp_r=temp_r) xx = bztTransp.compute_properties_doping(doping=doping) # 4 temps, 2 doping Conductivity_doping = bztTransp.Conductivity_doping Seebeck_doping = bztTransp.Seebeck_doping Kappa_doping = bztTransp.Kappa_doping Effective_mass_doping = bztTransp.Effective_mass_doping Power_Factor_doping = bztTransp.Power_Factor_doping mu_r_eV = bztTransp.mu_r_eV info = {} info["mu_r_eV"] = mu_r_eV info["temp_r"] = temp_r info["doping"] = doping info["Conductivity_doping"] = Conductivity_doping info["Seebeck_doping"] = Seebeck_doping info["Kappa_doping"] = Kappa_doping info["Effective_mass_doping"] = Effective_mass_doping info["Power_Factor_doping"] = Power_Factor_doping info["Conductivity_mu"] = bztTransp.Conductivity_mu info["Seebeck_mu"] = bztTransp.Seebeck_mu info["Kappa_mu"] = bztTransp.Kappa_mu info["Power_Factor_mu"] = bztTransp.Power_Factor_mu info["Effective_mass_mu"] = bztTransp.Effective_mass_mu info[ "Hall_carrier_conc_trace_mu"] = bztTransp.Hall_carrier_conc_trace_mu zt = [] temp_zt = [] for i, ii in enumerate(info["temp_r"]): for j, k in zip(info["Power_Factor_mu"][i], info["Kappa_mu"][i]): temp_zt.append(0.001 * j * ii / (k + k_latt)) zt.append(temp_zt) temp_zt = [] zt = np.array(zt) info["zt_mu"] = zt if write_json == True: f = open(fname, "w") f.write(json.dumps(info, cls=MontyEncoder)) f.close() return info else: print("File exists")
def setUp(self): vr = Vasprun(os.path.join(amset_files, 'vasprun.xml')) bs = vr.get_band_structure() num_electrons = vr.parameters['NELECT'] self.kpoints = np.array(vr.actual_kpoints) self.interpolater = BoltzTraP2Interpolater(bs, num_electrons)
def select_one_band_structure(): check_matplotlib() step_count=1 filename='vasprun.xml' check_file(filename) proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') vsr=Vasprun(filename) step_count+=1 filename='KPOINTS' check_file(filename) proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') bands = vsr.get_band_structure(filename, line_mode=True, efermi=vsr.efermi) nelect=vsr.parameters['NELECT'] nbands=bands.nb_bands if vsr.is_spin: proc_str="This Is a Spin-polarized Calculation." procs(proc_str,0,sp='-->>') ISPIN=2 else: if vsr.parameters['LNONCOLLINEAR']: proc_str="This Is a Non-Collinear Calculation." procs(proc_str,0,sp='-->>') ISPIN=3 else: proc_str="This Is a Non-Spin Calculation." procs(proc_str,0,sp='-->>') ISPIN=1 proc_str="Total band number is "+str(nbands) procs(proc_str,0,sp='-->>') proc_str="Total electron number is "+str(nelect) procs(proc_str,0,sp='-->>') print("which band would like to select ?") wait_sep() in_str="" while in_str=="": in_str=input().strip() selected_band=int(in_str) step_count+=1 filename="BAND_"+str(selected_band)+'.dat' proc_str="Writting Selected Band Structure Data to "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') if ISPIN==1 or ISPIN==3: band_data=bands.bands[Spin.up][selected_band-1]-vsr.efermi data=np.vstack((bands.distance,band_data)).T head_line="#%(key1)+12s%(key2)+13s"%{'key1':'K-Distance','key2':'Energy(ev)'} write_col_data(filename,data,head_line,len(band_data)) else: band_data_up=bands.bands[Spin.up][selected_band-1]-vsr.efermi band_data_down=bands.bands[Spin.down][selected_band-1]-vsr.efermi data=np.vstack((bands.distance,band_data_up,band_data_down)).T head_line="#%(key1)+12s%(key2)+13s%(key3)+15s"%{'key1':'K-Distance','key2':'UpEnergy(ev)','key3':'DownEnergy(ev)'} write_col_data(filename,data,head_line,len(band_data_up)) return
def run_task(self, fw_spec): kwargs = self.get("override_default_vasp_params") potcar_spec = self.get("potcar_spec", False) os.chdir(os.getcwd()) vrun = Vasprun("vasprun.xml", parse_potcar_file=False) bandgap = vrun.get_band_structure().get_band_gap()["energy"] structure = vrun.final_structure vis = MPScanRelaxSet(structure, bandgap=bandgap, **kwargs) vis.write_input(".", potcar_spec=potcar_spec)
def setUp(self): vr = Vasprun(os.path.join(gaas_files, "vasprun.xml.gz"), parse_projected_eigen=True) bs = vr.get_band_structure() num_electrons = vr.parameters["NELECT"] self.kpoints = np.array(vr.actual_kpoints) self.interpolater = Interpolator(bs, num_electrons, interpolate_projections=True, interpolation_factor=1)
def from_vasprun(cls, vasprun, **kwargs): from pymatgen.io.vasp import Vasprun if isinstance(vasprun, str): vasprun_gz = vasprun + ".gz" if Path(vasprun).exists(): vasprun = Vasprun(vasprun) elif Path(vasprun_gz).exists(): vasprun = Vasprun(vasprun_gz) bandstructure = vasprun.get_band_structure() nelect = vasprun.parameters["NELECT"] soc = vasprun.parameters["LSORBIT"] return cls(bandstructure, nelect, soc=soc, **kwargs)
def test_densify(self): # mesh = np.array([100, 100, 100]) # kpts = get_dense_kpoint_mesh_spglib(mesh, spg_order=True, shift=0.) # extra_points = np.array([[0.001, 0, 0], [0.002, 0, 0], [0.003, 0, 0]]) # pv = PeriodicVoronoi(Lattice([3, 0, 0, 0, 3, 0, 0, 0, 3]), # kpts, mesh, extra_points) # vols = pv.compute_volumes() # idx = np.argsort(vols) # all_k = np.concatenate([kpts, extra_points]) # print(all_k[idx][:12]) # print(vols[idx][:12]) initialize_amset_logger(log_error_traceback=True) vr = Vasprun(os.path.join(amset_files, "vasprun.xml.gz"), parse_projected_eigen=True) bs = vr.get_band_structure() inter = Interpolater(bs, vr.parameters["NELECT"], interpolate_projections=True, interpolation_factor=5) amset_data = inter.get_amset_data(energy_cutoff=2, bandgap=1.33) amset_data.calculate_dos() amset_data.set_doping_and_temperatures(doping=np.array([1e13]), temperatures=np.array([300])) amset_data.calculate_fd_cutoffs(fd_tolerance=0.000001) densifier = BandDensifier(inter, amset_data, energy_cutoff=2, bandgap=1.33) # print(amset_data.ir_to_full_kpoint_mapping[:200]) # print(max(amset_data.ir_to_full_kpoint_mapping)) # print(len(amset_data.ir_to_full_kpoint_mapping)) print("IR Kpoints idx max", max(amset_data.ir_kpoints_idx)) amset_data.set_extra_kpoints(*densifier.densify(0.008)) print(amset_data.ir_to_full_kpoint_mapping.max()) print(len(amset_data.ir_kpoints)) print(len(amset_data.ir_kpoints_idx)) print(max(amset_data.ir_kpoints_idx)) # print(max(amset_data.ir_to_full_kpoint_mapping)) # print(len(amset_data.ir_to_full_kpoint_mapping)) # x = extra_kpts[0][2] all_kpoints = amset_data.full_kpoints weights = amset_data.kpoint_weights mask = (all_kpoints[:, 2] == 0.) center_points = all_kpoints[mask][:, :2] center_labels = map("{:.3g}".format, weights[mask]) from scipy.spatial import Voronoi, voronoi_plot_2d vor = Voronoi(center_points) import matplotlib matplotlib.use("TkAgg") import matplotlib.pyplot as plt voronoi_plot_2d(vor) # plt.xlim((-0.48, -0.38)) # plt.ylim((-0.48, -0.38)) ax = plt.gca() for i, txt in enumerate(center_labels): kx = center_points[i][0] ky = center_points[i][1] if -0.38 > kx > -0.48 and -0.38 > ky > -0.48: ax.annotate(str(txt), (kx, ky)) plt.show()
def process_vasprun(self, dir_name, taskname, filename): """ Adapted from matgendb.creator Process a vasprun.xml file. """ vasprun_file = os.path.join(dir_name, filename) if self.bandstructure_mode: vrun = Vasprun(vasprun_file, parse_eigen=True, parse_projected_eigen=True) else: vrun = Vasprun(vasprun_file) d = vrun.as_dict() for k, v in { "formula_pretty": "pretty_formula", "composition_reduced": "reduced_cell_formula", "composition_unit_cell": "unit_cell_formula" }.items(): d[k] = d.pop(v) for k in ["eigenvalues", "projected_eigenvalues" ]: # large storage space breaks some docs if k in d["output"]: del d["output"][k] comp = Composition(d["composition_unit_cell"]) d["formula_anonymous"] = comp.anonymized_formula d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula d["dir_name"] = os.path.abspath(dir_name) d["completed_at"] = str( datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file))) d["density"] = vrun.final_structure.density # replace 'crystal' with 'structure' d["input"]["structure"] = d["input"].pop("crystal") d["output"]["structure"] = d["output"].pop("crystal") for k, v in { "energy": "final_energy", "energy_per_atom": "final_energy_per_atom" }.items(): d["output"][k] = d["output"].pop(v) if self.parse_dos and self.parse_dos != 'final': try: d["dos"] = vrun.complete_dos.as_dict() except: raise ValueError( "No valid dos data exist in {}.".format(dir_name)) if self.bandstructure_mode: bs = vrun.get_band_structure( line_mode=(self.bandstructure_mode == "line")) else: bs = vrun.get_band_structure() d["bandstructure"] = bs.as_dict() d["output"]["vbm"] = bs.get_vbm()["energy"] d["output"]["cbm"] = bs.get_cbm()["energy"] bs_gap = bs.get_band_gap() d["output"]["bandgap"] = bs_gap["energy"] d["output"]["is_gap_direct"] = bs_gap["direct"] d["output"]["is_metal"] = bs.is_metal() d["task"] = {"type": taskname, "name": taskname} # phonon-dfpt if hasattr(vrun, "force_constants"): d["output"]["force_constants"] = vrun.force_constants.tolist() d["output"][ "normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist() d["output"][ "normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist() return d
def process_vasprun(self, dir_name, taskname, filename): """ Adapted from matgendb.creator Process a vasprun.xml file. """ vasprun_file = os.path.join(dir_name, filename) vrun = Vasprun(vasprun_file, parse_potcar_file=self.parse_potcar_file) d = vrun.as_dict() # rename formula keys for k, v in { "formula_pretty": "pretty_formula", "composition_reduced": "reduced_cell_formula", "composition_unit_cell": "unit_cell_formula" }.items(): d[k] = d.pop(v) for k in ["eigenvalues", "projected_eigenvalues" ]: # large storage space breaks some docs if k in d["output"]: del d["output"][k] comp = Composition(d["composition_unit_cell"]) d["formula_anonymous"] = comp.anonymized_formula d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula d["dir_name"] = os.path.abspath(dir_name) d["completed_at"] = str( datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file))) d["density"] = vrun.final_structure.density # replace 'crystal' with 'structure' d["input"]["structure"] = d["input"].pop("crystal") d["output"]["structure"] = d["output"].pop("crystal") for k, v in { "energy": "final_energy", "energy_per_atom": "final_energy_per_atom" }.items(): d["output"][k] = d["output"].pop(v) # Process bandstructure and DOS if self.bandstructure_mode != False: bs = self.process_bandstructure(vrun) if bs: d["bandstructure"] = bs if self.parse_dos != False: dos = self.process_dos(vrun) if dos: d["dos"] = dos # Parse electronic information if possible. # For certain optimizers this is broken and we don't get an efermi resulting in the bandstructure try: bs = vrun.get_band_structure() bs_gap = bs.get_band_gap() d["output"]["vbm"] = bs.get_vbm()["energy"] d["output"]["cbm"] = bs.get_cbm()["energy"] d["output"]["bandgap"] = bs_gap["energy"] d["output"]["is_gap_direct"] = bs_gap["direct"] d["output"]["is_metal"] = bs.is_metal() if not bs_gap["direct"]: d["output"]["direct_gap"] = bs.get_direct_band_gap() if isinstance(bs, BandStructureSymmLine): d["output"]["transition"] = bs_gap["transition"] except Exception: logger.warning("Error in parsing bandstructure") if vrun.incar["IBRION"] == 1: logger.warning( "Vasp doesn't properly output efermi for IBRION == 1") if self.bandstructure_mode is True: logger.error(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) raise # Should roughly agree with information from .get_band_structure() above, subject to tolerances # If there is disagreement, it may be related to VASP incorrectly assigning the Fermi level try: band_props = vrun.eigenvalue_band_properties d["output"]["eigenvalue_band_properties"] = { "bandgap": band_props[0], "cbm": band_props[1], "vbm": band_props[2], "is_gap_direct": band_props[3] } except Exception: logger.warning("Error in parsing eigenvalue band properties") # store run name and location ,e.g. relax1, relax2, etc. d["task"] = {"type": taskname, "name": taskname} # include output file names d["output_file_paths"] = self.process_raw_data(dir_name, taskname=taskname) # parse axially averaged locpot if "locpot" in d["output_file_paths"] and self.parse_locpot: locpot = Locpot.from_file( os.path.join(dir_name, d["output_file_paths"]["locpot"])) d["output"]["locpot"] = { i: locpot.get_average_along_axis(i) for i in range(3) } if self.store_volumetric_data: for file in self.store_volumetric_data: if file in d["output_file_paths"]: try: # assume volumetric data is all in CHGCAR format data = Chgcar.from_file( os.path.join(dir_name, d["output_file_paths"][file])) d[file] = data.as_dict() except: raise ValueError("Failed to parse {} at {}.".format( file, d["output_file_paths"][file])) # parse force constants if hasattr(vrun, "force_constants"): d["output"]["force_constants"] = vrun.force_constants.tolist() d["output"][ "normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist() d["output"][ "normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist() # perform Bader analysis using Henkelman bader if self.parse_bader and "chgcar" in d["output_file_paths"]: suffix = '' if taskname == 'standard' else ".{}".format(taskname) bader = bader_analysis_from_path(dir_name, suffix=suffix) d["bader"] = bader return d
def process_vasprun(self, dir_name, taskname, filename): """ Adapted from matgendb.creator Process a vasprun.xml file. """ vasprun_file = os.path.join(dir_name, filename) vrun = Vasprun(vasprun_file) d = vrun.as_dict() # rename formula keys for k, v in {"formula_pretty": "pretty_formula", "composition_reduced": "reduced_cell_formula", "composition_unit_cell": "unit_cell_formula"}.items(): d[k] = d.pop(v) for k in ["eigenvalues", "projected_eigenvalues"]: # large storage space breaks some docs if k in d["output"]: del d["output"][k] comp = Composition(d["composition_unit_cell"]) d["formula_anonymous"] = comp.anonymized_formula d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula d["dir_name"] = os.path.abspath(dir_name) d["completed_at"] = str(datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file))) d["density"] = vrun.final_structure.density # replace 'crystal' with 'structure' d["input"]["structure"] = d["input"].pop("crystal") d["output"]["structure"] = d["output"].pop("crystal") for k, v in {"energy": "final_energy", "energy_per_atom": "final_energy_per_atom"}.items(): d["output"][k] = d["output"].pop(v) # Process bandstructure and DOS if self.bandstructure_mode != False: bs = self.process_bandstructure(vrun) if bs: d["bandstructure"] = bs if self.parse_dos != False: dos = self.process_dos(vrun) if dos: d["dos"] = dos # Parse electronic information if possible. # For certain optimizers this is broken and we don't get an efermi resulting in the bandstructure try: bs = vrun.get_band_structure() bs_gap = bs.get_band_gap() d["output"]["vbm"] = bs.get_vbm()["energy"] d["output"]["cbm"] = bs.get_cbm()["energy"] d["output"]["bandgap"] = bs_gap["energy"] d["output"]["is_gap_direct"] = bs_gap["direct"] d["output"]["is_metal"] = bs.is_metal() if not bs_gap["direct"]: d["output"]["direct_gap"] = bs.get_direct_band_gap() if isinstance(bs, BandStructureSymmLine): d["output"]["transition"] = bs_gap["transition"] except Exception: logger.warning("Error in parsing bandstructure") if vrun.incar["IBRION"] == 1: logger.warning("Vasp doesn't properly output efermi for IBRION == 1") if self.bandstructure_mode is True: logger.error(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) raise # store run name and location ,e.g. relax1, relax2, etc. d["task"] = {"type": taskname, "name": taskname} # include output file names d["output_file_paths"] = self.process_raw_data(dir_name, taskname=taskname) # parse axially averaged locpot if "locpot" in d["output_file_paths"] and self.parse_locpot: locpot = Locpot.from_file(os.path.join(dir_name, d["output_file_paths"]["locpot"])) d["output"]["locpot"] = {i: locpot.get_average_along_axis(i) for i in range(3)} if self.parse_chgcar != False: # parse CHGCAR file only for static calculations # TODO require static run later # if self.parse_chgcar == True and vrun.incar.get("NSW", 0) < 1: try: chgcar = self.process_chgcar(os.path.join(dir_name, d["output_file_paths"]["chgcar"])) except: raise ValueError("No valid charge data exist") d["chgcar"] = chgcar if self.parse_aeccar != False: try: chgcar = self.process_chgcar(os.path.join(dir_name, d["output_file_paths"]["aeccar0"])) except: raise ValueError("No valid charge data exist") d["aeccar0"] = chgcar try: chgcar = self.process_chgcar(os.path.join(dir_name, d["output_file_paths"]["aeccar2"])) except: raise ValueError("No valid charge data exist") d["aeccar2"] = chgcar # parse force constants if hasattr(vrun, "force_constants"): d["output"]["force_constants"] = vrun.force_constants.tolist() d["output"]["normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist() d["output"]["normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist() # Try and perform bader if self.parse_bader: try: bader = bader_analysis_from_path(dir_name, suffix=".{}".format(taskname)) except Exception as e: bader = "Bader analysis failed: {}".format(e) d["bader"] = bader return d
v = Vasprun('./vasprun.xml', parse_dos=True) cdos = v.complete_dos element_dos = cdos.get_element_dos() plotter = DosPlotter() plotter.add_dos_dict(element_dos) plotter.save_plot('plots/dos.pdf', img_format='pdf', xlim=None, ylim=None) # plotter.save_plot('spin-up_dos.pdf', img_format='pdf', xlim= None, ylim = [0,None]) # up-spin dos """ Plot Band """ from pymatgen.io.vasp import BSVasprun from pymatgen.electronic_structure.plotter import BSPlotter v = BSVasprun('./vasprun.xml', parse_projected_eigen=True) bs = v.get_band_structure(kpoints_filename='./KPOINTS', line_mode=True) bsplot = BSPlotter(bs) bsplot.get_plot(zero_to_efermi=True, ylim=[-5, 5]).savefig('plots/band.pdf') # add some features ax = plt.gca() #ax.set_title("Bandstructure", fontsize = 40) # use this for setting title xlim = ax.get_xlim() ax.hlines(0, xlim[0], xlim[1], linestyles="dashed", color="black") # add legend ax.plot((), (), "b-", label="spin up") ax.plot((), (), "r--", label="spin-down") ax.legend(fontsize=16, loc="upper left")
from pymatgen.io.vasp import Vasprun from pymatgen.electronic_structure.plotter import BSPlotter, BSPlotterProjected vr = Vasprun("nself/vasprun.xml") bs = vr.get_band_structure(kpoints_filename="nself/KPOINTS", line_mode=True) bsp = BSPlotter(bs) #plt = bsp.get_elt_projected_plots(zero_to_efermi=False) #plt.savefig("band_structure.png", format="png") bsp.save_plot(filename="band_structure.png", img_format="png")
if __name__ == "__main__": # read data # --------- # kpoints labels labels = [r"$L$", r"$\Gamma$", r"$X$", r"$U,K$", r"$\Gamma$"] # density of states dosrun = Vasprun("./DOS/vasprun.xml") spd_dos = dosrun.complete_dos.get_spd_dos() # bands run = Vasprun("./Bandes/vasprun.xml", parse_projected_eigen=True) bands = run.get_band_structure("./Bandes/KPOINTS", line_mode=True, efermi=dosrun.efermi) # set up matplotlib plot # ---------------------- # general options for plot font = {'family': 'serif', 'size': 24} plt.rc('font', **font) # set up 2 graph with aspec ration 2/1 # plot 1: bands diagram # plot 2: Density of States gs = GridSpec(1, 2, width_ratios=[2, 1]) fig = plt.figure(figsize=(11.69, 8.27)) fig.suptitle("Bands diagram of silicon")
def band_structure(): check_matplotlib() step_count=1 filename='vasprun.xml' check_file(filename) proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') vsr=Vasprun(filename) step_count+=1 filename='KPOINTS' check_file(filename) proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') bands = vsr.get_band_structure(filename, line_mode=True, efermi=vsr.efermi) step_count+=1 filename='OUTCAR' check_file(filename) proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') outcar=Outcar('OUTCAR') mag=outcar.as_dict()['total_magnetization'] if vsr.is_spin: proc_str="This Is a Spin-polarized Calculation." procs(proc_str,0,sp='-->>') tdos=vsr.tdos SpinUp_gap=tdos.get_gap(spin=Spin.up) cbm_vbm_up=tdos.get_cbm_vbm(spin=Spin.up) SpinDown_gap=tdos.get_gap(spin=Spin.down) cbm_vbm_down=tdos.get_cbm_vbm(spin=Spin.up) if SpinUp_gap > min_gap and SpinDown_gap > min_gap: is_metal=False is_semimetal=False elif SpinUp_gap > min_gap and SpinDown_gap < min_gap: is_metal=False is_semimetal=True elif SpinUp_gap < min_gap and SpinDown_gap > min_gap: is_metal=False is_semimetal=True elif SpinUp_gap < min_gap and SpinDown_gap < min_gap: is_metal=True is_semimetal=False if is_metal: proc_str="This Material Is a Metal." procs(proc_str,0,sp='-->>') if not is_metal and is_semimetal: proc_str="This Material Is a Semimetal." procs(proc_str,0,sp='-->>') else: proc_str="This Material Is a Semiconductor." procs(proc_str,0,sp='-->>') proc_str="Total magnetization is "+str(mag) procs(proc_str,0,sp='-->>') if mag > min_mag: proc_str="SpinUp : vbm=%f eV cbm=%f eV gap=%f eV"%(cbm_vbm_up[1],cbm_vbm_up[0],SpinUp_gap) procs(proc_str,0,sp='-->>') proc_str="SpinDown: vbm=%f eV cbm=%f eV gap=%f eV"%(cbm_vbm_down[1],cbm_vbm_down[0],SpinUp_gap) procs(proc_str,0,sp='-->>') else: proc_str="SpinUp : vbm=%f eV cbm=%f eV gap=%f eV"%(cbm_vbm_up[1],cbm_vbm_up[0],SpinUp_gap) procs(proc_str,0,sp='-->>') step_count+=1 filename="BAND.dat" proc_str="Writting Band Structure Data to "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') band_data_up=bands.bands[Spin.up] band_data_down=bands.bands[Spin.down] y_data_up=band_data_up.reshape(1,band_data_up.shape[0]*band_data_up.shape[1])[0]-vsr.efermi #shift fermi level to 0 y_data_down=band_data_down.reshape(1,band_data_down.shape[0]*band_data_down.shape[1])[0]-vsr.efermi #shift fermi level to 0 x_data=np.array(bands.distance*band_data_up.shape[0]) data=np.vstack((x_data,y_data_up,y_data_down)).T head_line="#%(key1)+12s%(key2)+13s%(key3)+15s"%{'key1':'K-Distance','key2':'UpEnergy(ev)','key3':'DownEnergy(ev)'} write_col_data(filename,data,head_line,band_data_up.shape[1]) else: if vsr.parameters['LNONCOLLINEAR']: proc_str="This Is a Non-Collinear Calculation." else: proc_str="This Is a Non-Spin Calculation." procs(proc_str,0,sp='-->>') cbm=bands.get_cbm()['energy'] vbm=bands.get_vbm()['energy'] gap=bands.get_band_gap()['energy'] if not bands.is_metal(): proc_str="This Material Is a Semiconductor." procs(proc_str,0,sp='-->>') proc_str="vbm=%f eV cbm=%f eV gap=%f eV"%(vbm,cbm,gap) procs(proc_str,0,sp='-->>') else: proc_str="This Material Is a Metal." procs(proc_str,0,sp='-->>') step_count+=1 filename3="BAND.dat" proc_str="Writting Band Structure Data to "+ filename3 +" File ..." procs(proc_str,step_count,sp='-->>') band_data=bands.bands[Spin.up] y_data=band_data.reshape(1,band_data.shape[0]*band_data.shape[1])[0]-vsr.efermi #shift fermi level to 0 x_data=np.array(bands.distance*band_data.shape[0]) data=np.vstack((x_data,y_data)).T head_line="#%(key1)+12s%(key2)+13s"%{'key1':'K-Distance','key2':'Energy(ev)'} write_col_data(filename3,data,head_line,band_data.shape[1]) step_count+=1 bsp=BSPlotter(bands) filename4="HighSymmetricPoints.dat" proc_str="Writting Label infomation to "+ filename4 +" File ..." procs(proc_str,step_count,sp='-->>') head_line="#%(key1)+12s%(key2)+12s%(key3)+12s"%{'key1':'index','key2':'label','key3':'position'} line=head_line+'\n' for i,label in enumerate(bsp.get_ticks()['label']): new_line="%(key1)12d%(key2)+12s%(key3)12f\n"%{'key1':i,'key2':label,'key3':bsp.get_ticks()['distance'][i]} line+=new_line line+='\n' write_col_data(filename4,line,'',str_data=True) try: step_count+=1 filename5="BAND.png" proc_str="Saving Plot to "+ filename5 +" File ..." procs(proc_str,step_count,sp='-->>') bsp.save_plot(filename5, img_format="png") except: print("Figure output fails !!!")
from pymatgen.electronic_structure.plotter import BSPlotter, BSPlotterProjected from pymatgen.io.vasp import Vasprun, BandStructure v = Vasprun("AgTe_bs/vasprun.xml") bands = v.get_band_structure(kpoints_filename="AgTe_bs/KPOINTS", line_mode=True) print(bands.get_band_gap()) plt = BSPlotter(bands) #plt.plot_brillouin() plt.get_plot(zero_to_efermi=True, vbm_cbm_marker=True, ylim=(-3, 3)).show() #plt.get_plot(zero_to_efermi=True,vbm_cbm_marker=True,ylim=(-2.2,0.5)).savefig(fname="bs.eps",img_format="eps")
def plot_bands(vasprun_dos, vasprun_bands, kpoints, element, ylim = (None, None)): # read data # --------- # kpoints labels # labels = [r"$L$", r"$\Gamma$", r"$X$", r"$U,K$", r"$\Gamma$"] labels = read_kpoint_labels(kpoints) # density of states # dosrun = Vasprun(vasprun_dos) dosrun = Vasprun(vasprun_bands) spd_dos = dosrun.complete_dos.get_spd_dos() # bands run = Vasprun(vasprun_bands, parse_projected_eigen=True) bands = run.get_band_structure(kpoints, line_mode=True, efermi=dosrun.efermi) # set up matplotlib plot # ---------------------- # general options for plot font = {'family': 'serif', 'size': 24} plt.rc('font', **font) # set up 2 graph with aspec ration 2/1 # plot 1: bands diagram # plot 2: Density of States gs = GridSpec(1, 2, width_ratios=[2, 1]) fig = plt.figure(figsize=(11.69, 8.27)) # fig.suptitle("Bands diagram of copper") ax1 = plt.subplot(gs[0]) ax2 = plt.subplot(gs[1]) # , sharey=ax1) # set ylim for the plot # --------------------- if ylim[0]: emin = ylim[0] else: emin = -10. if ylim[1]: emax = ylim[1] else: emax = 10. ax1.set_ylim(emin, emax) ax2.set_ylim(emin, emax) # Band Diagram # ------------ name = element pbands = bands.get_projections_on_elements_and_orbitals({name: ["s", "p", "d"]}) # print(pbands) # compute s, p, d normalized contributions contrib = np.zeros((bands.nb_bands, len(bands.kpoints), 3)) for b in range(bands.nb_bands): for k in range(len(bands.kpoints)): sc = pbands[Spin.up][b][k][name]["s"]**2 pc = pbands[Spin.up][b][k][name]["p"]**2 dc = pbands[Spin.up][b][k][name]["d"]**2 tot = sc + pc + dc if tot != 0.0: contrib[b, k, 0] = sc / tot contrib[b, k, 1] = pc / tot contrib[b, k, 2] = dc / tot # plot bands using rgb mapping for b in range(bands.nb_bands): rgbline(ax1, range(len(bands.kpoints)), [e - bands.efermi for e in bands.bands[Spin.up][b]], contrib[b, :, 0], contrib[b, :, 1], contrib[b, :, 2]) # style ax1.set_xlabel("k-points") ax1.set_ylabel(r"$E - E_f$ / eV") ax1.grid() # fermi level at 0 ax1.hlines(y=0, xmin=0, xmax=len(bands.kpoints), color="k", linestyle = '--', lw=1) # labels nlabs = len(labels) step = len(bands.kpoints) / (nlabs - 1) for i, lab in enumerate(labels): ax1.vlines(i * step, emin, emax, "k") ax1.set_xticks([i * step for i in range(nlabs)]) ax1.set_xticklabels(labels) ax1.set_xlim(0, len(bands.kpoints)) # Density of states # ---------------- ax2.set_yticklabels([]) ax2.grid() ax2.set_xlim(1e-4, 5) ax2.set_xticklabels([]) ax2.hlines(y=0, xmin=0, xmax=5, color="k", lw=2) ax2.set_xlabel("Density of States", labelpad=28) # spd contribution ax2.plot(spd_dos[OrbitalType.s].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "r-", label="3s", lw=2) ax2.plot(spd_dos[OrbitalType.p].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "g-", label="3p", lw=2) ax2.plot(spd_dos[OrbitalType.d].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "b-", label="3d", lw=2) # total dos ax2.fill_between(dosrun.tdos.densities[Spin.up], 0, dosrun.tdos.energies - dosrun.efermi, color=(0.7, 0.7, 0.7), facecolor=(0.7, 0.7, 0.7)) ax2.plot(dosrun.tdos.densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, color=(0.6, 0.6, 0.6), label="total DOS") # plot format style # ----------------- ax2.legend(fancybox=True, shadow=True, prop={'size': 18}) plt.subplots_adjust(wspace=0) # plt.show() plt.savefig("figs/bands.png")
def plot_bands_old(vasprun_dos, vasprun_bands, kpoints, element, ylim = (None, None)): """ This function is used to build plot of the electronic band structure along with the density of states (DOS) plot. It has feature to provide contributions from different elements to both band structure and DOS INPUT: - vasprun_dos (str) - path to the vasprun file of the DOS calculation - vasprun_band (str) - path to the vasprun file of the band structure calculation - kpoints (str) - path to the KPOINTS file of the band structure calculation - element (str) - label of the chemical element, for which the contribution to the band structure and DOS - ylim (tuple of floats) - energy range of the band structure and DOS plots, units are eV RETURN: None SOURCE: Credit https://github.com/gVallverdu/bandstructureplots TODO: Some improvements """ labels = read_kpoint_labels(kpoints) # density of states # dosrun = Vasprun(vasprun_dos) dosrun = Vasprun(vasprun_bands) spd_dos = dosrun.complete_dos.get_spd_dos() # bands run = Vasprun(vasprun_bands, parse_projected_eigen=True) bands = run.get_band_structure(kpoints, line_mode=True, efermi=dosrun.efermi) # set up matplotlib plot # ---------------------- # general options for plot font = {'family': 'serif', 'size': 24} plt.rc('font', **font) # set up 2 graph with aspec ration 2/1 # plot 1: bands diagram # plot 2: Density of States gs = GridSpec(1, 2, width_ratios=[2, 1]) fig = plt.figure(figsize=(11.69, 8.27)) # fig.suptitle("Bands diagram of copper") ax1 = plt.subplot(gs[0]) ax2 = plt.subplot(gs[1]) # , sharey=ax1) # set ylim for the plot # --------------------- if ylim[0]: emin = ylim[0] else: emin = -10. if ylim[1]: emax = ylim[1] else: emax = 10. ax1.set_ylim(emin, emax) ax2.set_ylim(emin, emax) # Band Diagram # ------------ name = element pbands = bands.get_projections_on_elements_and_orbitals({name: ["s", "p", "d"]}) # print(bands) # compute s, p, d normalized contributions contrib = np.zeros((bands.nb_bands, len(bands.kpoints), 3)) # print(pbands) for b in range(bands.nb_bands): for k in range(len(bands.kpoints)): # print(Spin.up) sc = pbands[Spin.up][b][k][name]["s"]**2 pc = pbands[Spin.up][b][k][name]["p"]**2 dc = pbands[Spin.up][b][k][name]["d"]**2 tot = sc + pc + dc if tot != 0.0: contrib[b, k, 0] = sc / tot contrib[b, k, 1] = pc / tot contrib[b, k, 2] = dc / tot # plot bands using rgb mapping for b in range(bands.nb_bands): rgbline(ax1, range(len(bands.kpoints)), [e - bands.efermi for e in bands.bands[Spin.up][b]], contrib[b, :, 0], contrib[b, :, 1], contrib[b, :, 2]) # style ax1.set_xlabel("k-points") ax1.set_ylabel(r"$E - E_f$ / eV") ax1.grid() # fermi level at 0 ax1.hlines(y=0, xmin=0, xmax=len(bands.kpoints), color="k", linestyle = '--', lw=1) # labels nlabs = len(labels) step = len(bands.kpoints) / (nlabs - 1) for i, lab in enumerate(labels): ax1.vlines(i * step, emin, emax, "k") ax1.set_xticks([i * step for i in range(nlabs)]) ax1.set_xticklabels(labels) ax1.set_xlim(0, len(bands.kpoints)) # Density of states # ---------------- ax2.set_yticklabels([]) ax2.grid() ax2.set_xlim(1e-4, 5) ax2.set_xticklabels([]) ax2.hlines(y=0, xmin=0, xmax=5, color="k", lw=2) ax2.set_xlabel("Density of States", labelpad=28) # spd contribution ax2.plot(spd_dos[OrbitalType.s].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "r-", label="3s", lw=2) ax2.plot(spd_dos[OrbitalType.p].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "g-", label="3p", lw=2) ax2.plot(spd_dos[OrbitalType.d].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "b-", label="3d", lw=2) # total dos ax2.fill_between(dosrun.tdos.densities[Spin.up], 0, dosrun.tdos.energies - dosrun.efermi, color=(0.7, 0.7, 0.7), facecolor=(0.7, 0.7, 0.7)) ax2.plot(dosrun.tdos.densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, color=(0.6, 0.6, 0.6), label="total DOS") # plot format style # ----------------- ax2.legend(fancybox=True, shadow=True, prop={'size': 18}) plt.subplots_adjust(wspace=0) # plt.show() makedir("figs/bands.png") plt.savefig("figs/bands.png")
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'] print(np.array(bs.bands[Spin.up]).shape) interp_params = get_energy_args(coeff_file, ibands=[vbm_idx+1, vbm_idx+2])
def test_get_energies_symprec(self): # vr = Vasprun(os.path.join(tin_dioxide_files, 'vasprun.xml.gz'), # parse_projected_eigen=True) vr = Vasprun(os.path.join(pbs_files, "vasprun.xml.gz"), parse_projected_eigen=True) bs = vr.get_band_structure() num_electrons = vr.parameters["NELECT"] interpolater = Interpolator(bs, num_electrons, interpolate_projections=True, interpolation_factor=1) ir_kpoints, weights, kpoints, ir_kpoints_idx, ir_to_full_idx = get_kpoints( [13, 15, 29], vr.final_structure, boltztrap_ordering=True, return_full_kpoints=True, ) initialize_amset_logger() ( energies, velocities, curvature, projections, sym_info, ) = interpolater.get_energies( kpoints, None, return_velocity=True, atomic_units=True, return_curvature=True, return_projections=True, symprec=0.1, return_vel_outer_prod=True, return_kpoint_mapping=True, ) ( energies_no_sym, velocities_no_sym, curvature_no_sym, projections_no_sym, ) = interpolater.get_energies( kpoints, None, return_velocity=True, atomic_units=True, return_curvature=True, return_projections=True, return_vel_outer_prod=True, symprec=None, ) np.testing.assert_array_equal(ir_to_full_idx, sym_info["ir_to_full_idx"]) np.testing.assert_array_equal(ir_kpoints_idx, sym_info["ir_kpoints_idx"]) # print(velocities[Spin.up][5, :, :, -3:]) # print(velocities_no_sym[Spin.up][5, :, :, -3:]) # print(sym_info["ir_to_full_idx"][-10:]) np.testing.assert_array_almost_equal(energies[Spin.up], energies_no_sym[Spin.up], decimal=12) np.testing.assert_array_almost_equal(velocities[Spin.up], velocities_no_sym[Spin.up], decimal=12) np.testing.assert_array_almost_equal(curvature[Spin.up], curvature_no_sym[Spin.up], decimal=12) for l in projections[Spin.up]: np.testing.assert_array_almost_equal( projections[Spin.up][l], projections_no_sym[Spin.up][l])
def process_vasprun(self, dir_name, taskname, filename): """ Adapted from matgendb.creator Process a vasprun.xml file. """ vasprun_file = os.path.join(dir_name, filename) vrun = Vasprun(vasprun_file) d = vrun.as_dict() # rename formula keys for k, v in {"formula_pretty": "pretty_formula", "composition_reduced": "reduced_cell_formula", "composition_unit_cell": "unit_cell_formula"}.items(): d[k] = d.pop(v) for k in ["eigenvalues", "projected_eigenvalues"]: # large storage space breaks some docs if k in d["output"]: del d["output"][k] comp = Composition(d["composition_unit_cell"]) d["formula_anonymous"] = comp.anonymized_formula d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula d["dir_name"] = os.path.abspath(dir_name) d["completed_at"] = str(datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file))) d["density"] = vrun.final_structure.density # replace 'crystal' with 'structure' d["input"]["structure"] = d["input"].pop("crystal") d["output"]["structure"] = d["output"].pop("crystal") for k, v in {"energy": "final_energy", "energy_per_atom": "final_energy_per_atom"}.items(): d["output"][k] = d["output"].pop(v) if self.parse_dos == True or (str(self.parse_dos).lower() == "auto" and vrun.incar.get("NSW", 1) == 0): try: d["dos"] = vrun.complete_dos.as_dict() except: raise ValueError("No valid dos data exist in {}.".format(dir_name)) # Band structure parsing logic if str(self.bandstructure_mode).lower() == "auto": # if line mode nscf if vrun.incar.get("ICHARG", 0) > 10 and vrun.kpoints.num_kpts > 0: bs_vrun = BSVasprun(vasprun_file, parse_projected_eigen=True) bs = bs_vrun.get_band_structure(line_mode=True) # else if nscf elif vrun.incar.get("ICHARG", 0) > 10: bs_vrun = BSVasprun(vasprun_file, parse_projected_eigen=True) bs = bs_vrun.get_band_structure() # else just regular calculation else: bs = vrun.get_band_structure() # only save the bandstructure if not moving ions if vrun.incar["NSW"] == 0: d["bandstructure"] = bs.as_dict() # legacy line/True behavior for bandstructure_mode elif self.bandstructure_mode: bs_vrun = BSVasprun(vasprun_file, parse_projected_eigen=True) bs = bs_vrun.get_band_structure(line_mode=(str(self.bandstructure_mode).lower() == "line")) d["bandstructure"] = bs.as_dict() # parse bandstructure for vbm/cbm/bandgap but don't save else: bs = vrun.get_band_structure() # Parse electronic information if possible. # For certain optimizers this is broken and we don't get an efermi resulting in the bandstructure try: bs_gap = bs.get_band_gap() d["output"]["vbm"] = bs.get_vbm()["energy"] d["output"]["cbm"] = bs.get_cbm()["energy"] d["output"]["bandgap"] = bs_gap["energy"] d["output"]["is_gap_direct"] = bs_gap["direct"] d["output"]["is_metal"] = bs.is_metal() if not bs_gap["direct"]: d["output"]["direct_gap"] = bs.get_direct_band_gap() if isinstance(bs, BandStructureSymmLine): d["output"]["transition"] = bs_gap["transition"] except Exception: if self.bandstructure_mode is True: import traceback logger.error(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) raise logger.warning("Error in parsing bandstructure") if vrun.incar["IBRION"] == 1: logger.warning("Vasp doesn't properly output efermi for IBRION == 1") d["task"] = {"type": taskname, "name": taskname} d["output_file_paths"] = self.process_raw_data(dir_name, taskname=taskname) if "locpot" in d["output_file_paths"] and self.parse_locpot: locpot = Locpot.from_file(os.path.join(dir_name, d["output_file_paths"]["locpot"])) d["output"]["locpot"] = {i: locpot.get_average_along_axis(i) for i in range(3)} if hasattr(vrun, "force_constants"): # phonon-dfpt d["output"]["force_constants"] = vrun.force_constants.tolist() d["output"]["normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist() d["output"]["normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist() return d
def projected_band_structure(): step_count=1 filename='vasprun.xml' check_file(filename) proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') vsr=Vasprun(filename) filename='PROCAR' check_file(filename) step_count+=1 proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') procar=Procar(filename) nbands=procar.nbands nions=procar.nions norbitals=len(procar.orbitals) nkpoints=procar.nkpoints step_count+=1 filename='KPOINTS' check_file(filename) proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') bands = vsr.get_band_structure(filename, line_mode=True, efermi=vsr.efermi) struct=vsr.final_structure (atom_index,in_str)=atom_selection(struct) if len(atom_index)==0: print("No atoms selected!") return # print(atom_index) if vsr.is_spin: proc_str="This Is a Spin-polarized Calculation." procs(proc_str,0,sp='-->>') ISPIN=2 contrib=np.zeros((nkpoints,nbands,norbitals,2)) for i in atom_index: contrib[:,:,:,0]=contrib[:,:,:,0]+procar.data[Spin.up][:,:,i,:] contrib[:,:,:,1]=contrib[:,:,:,1]+procar.data[Spin.down][:,:,i,:] for ispin in range(2): proj_band=contrib[:,:,:,ispin].reshape(nkpoints*nbands,norbitals) step_count+=1 if ispin==0: filename="PBAND_Up.dat" else: filename="PBAND_Down.dat" proc_str="Writting Projected Band Structure Data to "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') band_data=bands.bands[Spin.up] y_data=band_data.reshape(1,nbands*nkpoints)[0]-vsr.efermi #shift fermi level to 0 x_data=np.array(bands.distance*nbands) data=np.vstack((x_data,y_data,proj_band.T)).T tmp1_str="#%(key1)+12s%(key2)+12s" tmp2_dic={'key1':'K-Distance','key2':'Energy(ev)'} for i in range(norbitals): tmp1_str+="%(key"+str(i+3)+")+12s" tmp2_dic["key"+str(i+3)]=procar.orbitals[i] # print(tmp1_str) atom_index_str=[str(x+1) for x in atom_index] head_line1="#String: "+in_str+'\n#Selected atom: ' +' '.join(atom_index_str)+'\n' head_line2=tmp1_str % tmp2_dic head_line=head_line1+head_line2 write_col_data(filename,data,head_line,nkpoints) else: if vsr.parameters['LNONCOLLINEAR']: proc_str="This Is a Non-Collinear Calculation." procs(proc_str,0,sp='-->>') ISPIN=3 else: proc_str="This Is a Non-Spin Calculation." procs(proc_str,0,sp='-->>') ISPIN=1 contrib=np.zeros((nkpoints,nbands,norbitals)) for i in atom_index: contrib[:,:,:]=contrib[:,:,:]+procar.data[Spin.up][:,:,i,:] proj_band=contrib.reshape(nkpoints*nbands,norbitals) step_count+=1 filename="PBAND.dat" proc_str="Writting Projected Band Structure Data to "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') band_data=bands.bands[Spin.up] y_data=band_data.reshape(1,nbands*nkpoints)[0]-vsr.efermi #shift fermi level to 0 x_data=np.array(bands.distance*nbands) data=np.vstack((x_data,y_data,proj_band.T)).T tmp1_str="#%(key1)+12s%(key2)+12s" tmp2_dic={'key1':'K-Distance','key2':'Energy(ev)'} for i in range(norbitals): tmp1_str+="%(key"+str(i+3)+")+12s" tmp2_dic["key"+str(i+3)]=procar.orbitals[i] # print(tmp1_str) atom_index_str=[str(x+1) for x in atom_index] head_line1="#String: "+in_str+'\n#Selected atom: ' +' '.join(atom_index_str)+'\n' head_line2=tmp1_str % tmp2_dic head_line=head_line1+head_line2 write_col_data(filename,data,head_line,nkpoints) step_count+=1 bsp=BSPlotter(bands) filename="HighSymmetricPoints.dat" proc_str="Writting Label infomation to "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') head_line="#%(key1)+12s%(key2)+12s%(key3)+12s"%{'key1':'index','key2':'label','key3':'position'} line=head_line+'\n' for i,label in enumerate(bsp.get_ticks()['label']): new_line="%(key1)12d%(key2)+12s%(key3)12f\n"%{'key1':i,'key2':label,'key3':bsp.get_ticks()['distance'][i]} line+=new_line write_col_data(filename,line,'',str_data=True)
def optplot( modes=("absorption", ), filenames=None, codes="vasp", prefix=None, directory=None, gaussian=None, band_gaps=None, labels=None, average=True, height=6, width=6, xmin=0, xmax=None, ymin=0, ymax=1e5, colours=None, style=None, no_base_style=None, image_format="pdf", dpi=400, plt=None, fonts=None, units="eV", ): """A script to plot optical absorption spectra from VASP calculations. Args: modes (:obj:`list` or :obj:`tuple`): Ordered list of :obj:`str` determining properties to plot. Accepted options are 'absorption' (default), 'eps', 'eps-real', 'eps-im', 'n', 'n-real', 'n-im', 'loss' (equivalent to n-im). filenames (:obj:`str` or :obj:`list`, optional): Path to data file. For VASP this is a *vasprun.xml* file (can be gzipped); for Questaal the *opt.ext* file from *lmf* or *eps_BSE.out* from *bethesalpeter* may be used. Alternatively, a list of paths can be provided, in which case the absorption spectra for each will be plotted concurrently. codes (:obj:`str` or :obj:`list`, optional): Original calculator. Accepted values are 'vasp' and 'questaal'. Items should correspond to filenames. prefix (:obj:`str`, optional): Prefix for file names. directory (:obj:`str`, optional): The directory in which to save files. gaussian (:obj:`float`): Standard deviation for gaussian broadening. band_gaps (:obj:`float`, :obj:`str` or :obj:`list`, optional): The band gap as a :obj:`float`, in eV, plotted as a dashed line. If plotting multiple spectra then a :obj:`list` of band gaps can be provided. Band gaps can be provided as a floating-point number or as a path to a *vasprun.xml* file. To skip over a line, set its bandgap to zero or a negative number to place it outside the visible range. labels (:obj:`str` or :obj:`list`): A label to identify the spectra. If plotting multiple spectra then a :obj:`list` of labels can be provided. average (:obj:`bool`, optional): Average the dielectric response across all lattice directions. Defaults to ``True``. height (:obj:`float`, optional): The height of the plot. width (:obj:`float`, optional): The width of the plot. xmin (:obj:`float`, optional): The minimum energy on the x-axis. xmax (:obj:`float`, optional): The maximum energy on the x-axis. ymin (:obj:`float`, optional): The minimum absorption intensity on the y-axis. ymax (:obj:`float`, optional): The maximum absorption intensity on the y-axis. colours (:obj:`list`, optional): A :obj:`list` of colours to use in the plot. The colours can be specified as a hex code, set of rgb values, or any other format supported by matplotlib. style (:obj:`list` or :obj:`str`, optional): (List of) matplotlib style specifications, to be composed on top of Sumo base style. no_base_style (:obj:`bool`, optional): Prevent use of sumo base style. This can make alternative styles behave more predictably. image_format (:obj:`str`, optional): The image file format. Can be any format supported by matplotlib, including: png, jpg, pdf, and svg. Defaults to pdf. dpi (:obj:`int`, optional): The dots-per-inch (pixel density) for the image. plt (:obj:`matplotlib.pyplot`, optional): A :obj:`matplotlib.pyplot` object to use for plotting. fonts (:obj:`list`, optional): Fonts to use in the plot. Can be a a single font, specified as a :obj:`str`, or several fonts, specified as a :obj:`list` of :obj:`str`. units (:obj:`str`, optional): X-axis units for the plot. 'eV' for energy in electronvolts or 'nm' for wavelength in nanometers. Defaults to 'eV'. Returns: A matplotlib pyplot object. """ # Don't write files if this is being done to manipulate existing plt save_files = False if plt else True # BUILD LIST OF FILES AUTOMATICALLY IF NECESSARY if codes == "vasp": if not filenames: if os.path.exists("vasprun.xml"): filenames = ["vasprun.xml"] elif os.path.exists("vasprun.xml.gz"): filenames = ["vasprun.xml.gz"] else: logging.error("ERROR: No vasprun.xml found!") sys.exit() elif codes == "questaal": if not filenames: if len(glob("opt.*")) > 0: filenames = glob("opt.*") if len(filenames) == 1: logging.info("Found optics file: " + filenames[0]) else: logging.info("Found optics files: " + ", ".join(filenames)) if isinstance(filenames, str): filenames = [filenames] if isinstance(codes, str): codes = [codes] * len(filenames) elif len(codes) == 1: codes = list(codes) * len(filenames) # ITERATE OVER FILES READING DIELECTRIC DATA dielectrics = [] auto_labels = [] auto_band_gaps = [] for i, (filename, code) in enumerate(zip(filenames, codes)): if code == "vasp": vr = Vasprun(filename) dielectrics.append(vr.dielectric) auto_labels.append( latexify( vr.final_structure.composition.reduced_formula).replace( "$_", r"$_\mathregular")) if isinstance(band_gaps, list) and not band_gaps: # band_gaps = [], auto band gap requested auto_band_gaps.append( vr.get_band_structure().get_band_gap()["energy"]) else: auto_band_gaps.append(None) elif code == "questaal": if not save_files: out_filename = None elif len(filenames) == 1: out_filename = "dielectric.dat" else: out_filename = f"dielectric_{i + 1}.dat" dielectrics.append( questaal.dielectric_from_file(filename, out_filename)) auto_band_gaps.append(None) auto_labels.append(filename.split(".")[-1]) if isinstance(band_gaps, list) and not band_gaps: logging.info("Bandgap requested but not supported for Questaal" " file {}: skipping...".format(filename)) else: raise Exception(f'Code selection "{code}" not recognised') if not labels and len(filenames) > 1: labels = auto_labels # PROCESS DIELECTRIC DATA: BROADENING AND DERIVED PROPERTIES if gaussian: dielectrics = [broaden_eps(d, gaussian) for d in dielectrics] # initialize spectrum data ready to append from each dataset abs_data = OrderedDict() for mode in modes: abs_data.update({mode: []}) # for each calculation, get all required properties and append to data for d in dielectrics: # TODO: add support for other eigs and full modes energies, properties = calculate_dielectric_properties( d, set(modes), mode="average" if average else "trace") for mode, spectrum in properties.items(): abs_data[mode].append((energies, spectrum)) if isinstance(band_gaps, list) and not band_gaps: # empty list therefore use bandgaps collected from vasprun files band_gaps = auto_band_gaps elif isinstance(band_gaps, list): # list containing filenames and/or values: mutate the list in-place for i, item in enumerate(band_gaps): if item is None: pass elif _floatable(item): band_gaps[i] = float(item) elif "vasprun" in item: band_gaps[i] = (Vasprun( item).get_band_structure().get_band_gap()["energy"]) else: raise ValueError( f"Format not recognised for auto bandgap: {item}.") plotter = SOpticsPlotter(abs_data, band_gap=band_gaps, label=labels) plt = plotter.get_plot( width=width, height=height, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, colours=colours, dpi=dpi, plt=plt, fonts=fonts, style=style, no_base_style=no_base_style, units=units, ) if save_files: basename = "absorption" if prefix: basename = f"{prefix}_{basename}" image_filename = f"{basename}.{image_format}" if directory: image_filename = os.path.join(directory, image_filename) plt.savefig(image_filename, format=image_format, dpi=dpi) for mode, data in abs_data.items(): basename = "absorption" if mode == "abs" else mode write_files(data, basename=basename, prefix=prefix, directory=directory) else: return plt
def carrier_mobility(calc_init=(), calc_deform_x=(), calc_deform_y=(), vbm=1, vbm_point=0, cbm=2, cbm_point=0, deform_x=(), n_points_x=2, deform_y=(), n_points_y=2, temperature_range=(300, 900), temperature_ref=300, effective_mass_el={}, effective_mass_xy_el={}, effective_mass_hole={}, effective_mass_xy_hole={}, lab_size=15, tick_size=15, leg_size=15, fig_size=(9, 17), fig_title='', xlim=(), ylim_elastic=(), ylim_deform=(), expression='Guo2021_JMCC', database=None, folder=''): from math import pi, sqrt, acos, sin from pymatgen.io.vasp import Vasprun, Outcar from pymatgen.electronic_structure.core import Spin, OrbitalType from analysis_functions import Approximation as A import matplotlib.pyplot as plt import matplotlib.gridspec as gspec # Transformation coefficients ang = 1e-10 # Angstrom, m ev_in_j = 1.60217662e-19 # Electron-volt, J # Functions for calculation of the carrier mobility def carrier_Guo2021_JMCC(t, c2d, el, m, md): # Constants e = 1.60217662e-19 # Electron charge, Coulomb m_e = 9.10938356e-31 # Electron mass, kg k_B = 1.38064852e-23 # Boltzmann constant, J/K h = 6.62607004e-34 # Plank constant, J*s mu = (e * (h / (2 * pi))**3 * c2d * 10000) / (k_B * t * m * md * m_e**2 * el**2) return mu # Lists of deformation along x and y axes step_x = (deform_x[1] - deform_x[0]) / (n_points_x - 1) eps_x = [deform_x[0] + step_x * i for i in range(n_points_x)] step_y = (deform_y[1] - deform_y[0]) / (n_points_y - 1) eps_y = [deform_y[0] + step_y * i for i in range(n_points_y)] # Reading energies energy_x = [] energy_vbm_x = [] energy_cbm_x = [] for i in calc_deform_x[2]: calc_cur = database[(calc_deform_x[0], calc_deform_x[1], i)] energy_x.append(calc_cur.energy_sigma0) path_vasprun = calc_cur.path['output'].replace('OUTCAR', 'vasprun.xml') path_kpoints = calc_cur.path['output'].replace( str(i) + '.OUTCAR', 'IBZKPT') run = Vasprun(path_vasprun, parse_projected_eigen=True) dosrun = Vasprun(path_vasprun) try: bands = run.get_band_structure(path_kpoints, line_mode=True, efermi=dosrun.efermi) except Exception: path_kpoints = calc_cur.path['output'].replace( str(i) + '.OUTCAR', 'KPOINTS') bands = run.get_band_structure(path_kpoints, line_mode=True, efermi=dosrun.efermi) energy_vbm_x.append(bands.bands[Spin.up][vbm - 1][vbm_point]) energy_cbm_x.append(bands.bands[Spin.up][cbm - 1][cbm_point]) energy_y = [] energy_vbm_y = [] energy_cbm_y = [] for i in calc_deform_y[2]: calc_cur = database[(calc_deform_y[0], calc_deform_y[1], i)] energy_y.append(calc_cur.energy_sigma0) path_vasprun = calc_cur.path['output'].replace('OUTCAR', 'vasprun.xml') path_kpoints = calc_cur.path['output'].replace( str(i) + '.OUTCAR', 'IBZKPT') run = Vasprun(path_vasprun, parse_projected_eigen=True) dosrun = Vasprun(path_vasprun) try: bands = run.get_band_structure(path_kpoints, line_mode=True, efermi=dosrun.efermi) except Exception: path_kpoints = calc_cur.path['output'].replace( str(i) + '.OUTCAR', 'KPOINTS') bands = run.get_band_structure(path_kpoints, line_mode=True, efermi=dosrun.efermi) energy_vbm_y.append(bands.bands[Spin.up][vbm - 1][vbm_point]) energy_cbm_y.append(bands.bands[Spin.up][cbm - 1][cbm_point]) # Calculation of the initial surface area s0 a = list(database[calc_init].end.rprimd[0]) b = list(database[calc_init].end.rprimd[1]) mod_a = sqrt(a[0]**2 + a[1]**2 + a[2]**2) mod_b = sqrt(b[0]**2 + b[1]**2 + b[2]**2) sc_ab = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] angle = acos(sc_ab / (mod_a * mod_b)) s0 = mod_a * mod_b * sin(angle) # ********************************************* 2D elastic moduli ******************************************** # 2D Elastic modulus # Deformation along x direction ek1 = A() ek1.aprx_lsq('a0*x**2+a1*x+a2', 3, eps_x, energy_x) C_2D_x = ek1.coefs[0] * ev_in_j / (s0 * ang**2) a0_x = ek1.coefs[0] a1_x = ek1.coefs[1] a2_x = ek1.coefs[2] eps_x_fit = [ deform_x[0] + (deform_x[1] - deform_x[0]) / 999 * i for i in range(1000) ] energy_x_fit = [a0_x * i**2 + a1_x * i + a2_x for i in eps_x_fit] # Deformation along y direction ek2 = A() ek2.aprx_lsq('a0*x**2+a1*x+a2', 3, eps_y, energy_y) C_2D_y = ek2.coefs[0] * ev_in_j / (s0 * ang**2) a0_y = ek2.coefs[0] a1_y = ek2.coefs[1] a2_y = ek2.coefs[2] eps_y_fit = [ deform_y[0] + (deform_y[1] - deform_y[0]) / 999 * i for i in range(1000) ] energy_y_fit = [a0_y * i**2 + a1_y * i + a2_y for i in eps_y_fit] # ************************************************************************************************************ # ***************************************** Deformation potential ******************************************** # Deformation potential # X direction ek3 = A() ek3.aprx_lsq('a0*x+a1', 2, eps_x, energy_vbm_x) E_l_hole_x = ek3.coefs[0] * ev_in_j vbm_x_0 = ek3.coefs[0] vbm_x_1 = ek3.coefs[1] ek4 = A() ek4.aprx_lsq('a0*x+a1', 2, eps_x, energy_cbm_x) E_l_el_x = ek4.coefs[0] * ev_in_j cbm_x_0 = ek4.coefs[0] cbm_x_1 = ek4.coefs[1] energy_vbm_x_fit = [vbm_x_0 * i + vbm_x_1 for i in eps_x_fit] energy_cbm_x_fit = [cbm_x_0 * i + cbm_x_1 for i in eps_x_fit] # Y direction ek5 = A() ek5.aprx_lsq('a0*x+a1', 2, eps_y, energy_vbm_y) E_l_hole_y = ek5.coefs[0] * ev_in_j vbm_y_0 = ek5.coefs[0] vbm_y_1 = ek5.coefs[1] ek6 = A() ek6.aprx_lsq('a0*x+a1', 2, eps_y, energy_cbm_y) E_l_el_y = ek6.coefs[0] * ev_in_j cbm_y_0 = ek6.coefs[0] cbm_y_1 = ek6.coefs[1] energy_vbm_y_fit = [vbm_y_0 * i + vbm_y_1 for i in eps_y_fit] energy_cbm_y_fit = [cbm_y_0 * i + cbm_y_1 for i in eps_y_fit] # Writing files with the energy dependencies on deformation value f = open(folder + '/elastic_x.out', 'w') for i in range(len(eps_x)): f.write('{0:15.5f} {1:15.10f}'.format(eps_x[i], energy_x[i]) + '\n') f.close() f = open(folder + '/elastic_y.out', 'w') for i in range(len(eps_y)): f.write('{0:15.5f} {1:15.10f}'.format(eps_y[i], energy_y[i]) + '\n') f.close() f = open(folder + '/elastic_x_fit.out', 'w') for i in range(len(eps_x_fit)): f.write('{0:15.5f} {1:15.10f}'.format(eps_x_fit[i], energy_x_fit[i]) + '\n') f.close() f = open(folder + '/elastic_y_fit.out', 'w') for i in range(len(eps_y_fit)): f.write('{0:15.5f} {1:15.10f}'.format(eps_y_fit[i], energy_y_fit[i]) + '\n') f.close() f = open(folder + '/deformation_potential_x_hole.out', 'w') for i in range(len(eps_x)): f.write('{0:15.5f} {1:15.10f}'.format(eps_x[i], energy_vbm_x[i]) + '\n') f.close() f = open(folder + '/deformation_potential_x_electron.out', 'w') for i in range(len(eps_x)): f.write('{0:15.5f} {1:15.10f}'.format(eps_x[i], energy_cbm_x[i]) + '\n') f.close() f = open(folder + '/deformation_potential_x_hole_fit.out', 'w') for i in range(len(eps_x_fit)): f.write( '{0:15.5f} {1:15.10f}'.format(eps_x_fit[i], energy_vbm_x_fit[i]) + '\n') f.close() f = open(folder + '/deformation_potential_x_electron_fit.out', 'w') for i in range(len(eps_x_fit)): f.write( '{0:15.5f} {1:15.10f}'.format(eps_x_fit[i], energy_cbm_x_fit[i]) + '\n') f.close() f = open(folder + '/deformation_potential_y_hole.out', 'w') for i in range(len(eps_y)): f.write('{0:15.5f} {1:15.10f}'.format(eps_y[i], energy_vbm_y[i]) + '\n') f.close() f = open(folder + '/deformation_potential_y_electron.out', 'w') for i in range(len(eps_y)): f.write('{0:15.5f} {1:15.10f}'.format(eps_y[i], energy_cbm_y[i]) + '\n') f.close() f = open(folder + '/deformation_potential_y_hole_fit.out', 'w') for i in range(len(eps_y_fit)): f.write( '{0:15.5f} {1:15.10f}'.format(eps_y_fit[i], energy_vbm_y_fit[i]) + '\n') f.close() f = open(folder + '/deformation_potential_y_electron_fit.out', 'w') for i in range(len(eps_y_fit)): f.write( '{0:15.5f} {1:15.10f}'.format(eps_y_fit[i], energy_cbm_y_fit[i]) + '\n') f.close() # ************************************************************************************************************ # Figure with Elastic moduli and Deformation potential interval = 0.05 npoint = 50 precision = 0.000001 shift_left = 100000.15 shift_right = 100000.20 # Use GridSpec to set subplots gs = gspec.GridSpec(1, 2, width_ratios=[1.0, 1.0], height_ratios=[1.0]) # height_ratios = [5, 5, 5] gs.update(bottom=0.07, hspace=0.17, wspace=0.25, top=0.93, right=0.97, left=0.1) # ========================== Vanadium ================================= plt1 = plt.subplot(gs[0, 0]) plt1.plot(eps_x, energy_x, linewidth=2, linestyle='', marker='o', markersize=7, color='red') plt1.plot(eps_x_fit, energy_x_fit, linewidth=2, linestyle='-', color='red', label='x: $C_{2D} = $' + '{0:7.2f}'.format(C_2D_x) + ' N/m') plt1.plot(eps_y, energy_y, linewidth=2, linestyle='', marker='o', markersize=7, color='blue') plt1.plot(eps_y_fit, energy_y_fit, linewidth=2, linestyle='-', color='blue', label='y: $C_{2D} = $' + '{0:7.2f}'.format(C_2D_y) + ' N/m') plt.xticks(fontsize=tick_size) plt.yticks(fontsize=tick_size) plt.xlabel('$\epsilon$', fontsize=lab_size) plt.ylabel('Energy, eV', fontsize=lab_size) if xlim: plt1.set_xlim(xlim[0], xlim[1]) if ylim_elastic: plt1.set_ylim(ylim_elastic[0], ylim_elastic[1]) plt1.legend(bbox_to_anchor=(0.5, 0.5), borderaxespad=0., labelspacing=0.3, numpoints=1, frameon=True, fancybox=True, markerscale=1., handletextpad=0.3, fontsize=leg_size) # ========================== Chromium ================================= plt2 = plt.subplot(gs[0, 1]) plt2.plot(eps_x, energy_vbm_x, linewidth=2, linestyle='', marker='o', markersize=7, color='red') plt2.plot(eps_x_fit, energy_vbm_x_fit, linewidth=2, linestyle='-', color='red', label='x: VBM $E_{l} = $' + '{0:7.2f}'.format(E_l_hole_x / ev_in_j) + ' eV') plt2.plot(eps_x, energy_cbm_x, linewidth=2, linestyle='', marker='o', markersize=7, color='blue') plt2.plot(eps_x_fit, energy_cbm_x_fit, linewidth=2, linestyle='-', color='blue', label='x: CBM $E_{l} = $' + '{0:7.2f}'.format(E_l_el_x / ev_in_j) + ' eV') plt2.plot(eps_y, energy_vbm_y, linewidth=2, linestyle='', marker='s', markersize=7, color='orange') plt2.plot(eps_y_fit, energy_vbm_y_fit, linewidth=2, linestyle='-', color='orange', label='y: VBM $E_{l} = $' + '{0:7.2f}'.format(E_l_hole_y / ev_in_j) + ' eV') plt2.plot(eps_y, energy_cbm_y, linewidth=2, linestyle='', marker='s', markersize=7, color='green') plt2.plot(eps_y_fit, energy_cbm_y_fit, linewidth=2, linestyle='-', color='green', label='y: CBM $E_{l} = $' + '{0:7.2f}'.format(E_l_el_y / ev_in_j) + ' eV') plt.xticks(fontsize=tick_size) plt.yticks(fontsize=tick_size) plt.xlabel('$\epsilon$', fontsize=lab_size) plt.ylabel('Energy, eV', fontsize=lab_size) if xlim: plt2.set_xlim(xlim[0], xlim[1]) if ylim_deform: plt2.set_ylim(ylim_deform[0], ylim_deform[1]) plt2.legend(bbox_to_anchor=(0.5, 0.5), borderaxespad=0., labelspacing=0.3, numpoints=1, frameon=True, fancybox=True, markerscale=1., handletextpad=0.3, fontsize=leg_size) # Make figure with the chosen size fig = plt.figure(1, dpi=600) fig.set_figheight(fig_size[0]) fig.set_figwidth(fig_size[1]) fig.savefig(folder + '/Elastic_moduli_Deformation_potential.pdf', format="pdf", dpi=600) plt.clf() plt.cla() # Calculation of the carrier mobility # Check if the temperature range option is used if temperature_range: step_t = (temperature_range[1] - temperature_range[0]) / (1000 - 1) t_list = [temperature_range[0] + i * step_t for i in range(1000)] # Make calculations f = open(folder + '/carrier_mobility_t' + str(temperature_ref) + '.out', 'w') if expression == 'Guo2021_JMCC': cite = 'The expression for the carrier mobility was taken from \n S.-D. Guo, W.-Q. Mu, Y.-T. Zhu, R.-Y. Han, W.-C. Ren, J. Mater. Chem. C. 9 (2021) 2464–2473. doi:10.1039/D0TC05649A. (Eq. 4)\n' f.write(cite) f.write('\n') f.write('Temperature ' + str(temperature_ref) + ' K\n') f.write('{0:^15s}{1:^10s}{2:^15s}{3:^15s}{4:^15s}{5:^17s}'.format( 'Carrier type', 'Direction', 'C_2D, N/m', 'm*, m_e', 'E_l, eV', 'mu_2D, cm^2V^(-1)s^(-1)') + '\n') if expression == 'Guo2021_JMCC': function_cm = carrier_Guo2021_JMCC else: raise RuntimeError( 'Choose the appropriate expression for carrier mobility!!!') for j in effective_mass_el.keys(): f.write('CBM -> ' + j + '\n') if expression == 'Guo2021_JMCC': mu_el_x = function_cm(t=temperature_ref, c2d=C_2D_x, el=E_l_el_x, m=effective_mass_el[j], md=effective_mass_xy_el['X']) mu_el_y = function_cm(t=temperature_ref, c2d=C_2D_y, el=E_l_el_y, m=effective_mass_el[j], md=effective_mass_xy_el['Y']) f.write( '{0:^15s}{1:^10s}{2:^15.2f}{3:^15.2f}{4:^15.2f}{5:^17.2f}'.format( 'Electron', 'x', C_2D_x, effective_mass_el[j], E_l_el_x / ev_in_j, mu_el_x) + '\n') f.write( '{0:^15s}{1:^10s}{2:^15.2f}{3:^15.2f}{4:^15.2f}{5:^17.2f}'.format( 'Electron', 'y', C_2D_y, effective_mass_el[j], E_l_el_y / ev_in_j, mu_el_y) + '\n') # If the temperature range is set if temperature_range: mu_el_x_list = [ function_cm(t=i, c2d=C_2D_x, el=E_l_el_x, m=effective_mass_el[j], md=effective_mass_xy_el['X']) for i in t_list ] mu_el_y_list = [ function_cm(t=i, c2d=C_2D_y, el=E_l_el_y, m=effective_mass_el[j], md=effective_mass_xy_el['Y']) for i in t_list ] f1 = open( folder + '/carrier_mobility_t' + str(temperature_range[0]) + '_' + str(temperature_range[1]) + '_el_CBM_' + j + '_X.out', 'w') for i in range(len(t_list)): f1.write('{0:^15.2f} {1:^15.2f}'.format( t_list[i], mu_el_x_list[i]) + '\n') f1.close() f1 = open( folder + '/carrier_mobility_t' + str(temperature_range[0]) + '_' + str(temperature_range[1]) + '_el_CBM_' + j + '_Y.out', 'w') for i in range(len(t_list)): f1.write('{0:^15.2f} {1:^15.2f}'.format( t_list[i], mu_el_y_list[i]) + '\n') f1.close() # Make figure for the temperature dependence of the carrier mobility of electrons plt.plot(t_list, mu_el_x_list, linewidth=2, linestyle='-', color='red', label='X') plt.plot(t_list, mu_el_y_list, linewidth=2, linestyle='-', color='blue', label='Y') plt.xlabel('Temperature, K', fontsize=lab_size) plt.ylabel('$\mu_{2D}, cm^2V^{-1}s^{-1}$', fontsize=lab_size) plt.legend(bbox_to_anchor=(0.5, 0.5), borderaxespad=0., labelspacing=0.3, numpoints=1, frameon=True, fancybox=True, markerscale=1., handletextpad=0.3, fontsize=leg_size) plt.title('Electron CBM ->' + j) fig = plt.figure(1) fig.set_figheight(9) fig.set_figwidth(9) fig.savefig(folder + '/carrier_mobility_t' + str(temperature_range[0]) + '_' + str(temperature_range[1]) + '_el_CBM_' + j + '_XY.pdf', format="pdf", dpi=600) plt.clf() plt.cla() for j in effective_mass_hole.keys(): f.write('VBM -> ' + j + '\n') if expression == 'Guo2021_JMCC': mu_hole_x = function_cm(t=temperature_ref, c2d=C_2D_x, el=E_l_hole_x, m=effective_mass_hole[j], md=effective_mass_xy_hole['X']) mu_hole_y = function_cm(t=temperature_ref, c2d=C_2D_y, el=E_l_hole_y, m=effective_mass_hole[j], md=effective_mass_xy_hole['Y']) f.write('{0:^15s}{1:^10s}{2:^15.2f}{3:^15.2f}{4:^15.2f}{5:^17.2f}'. format('Hole', 'x', C_2D_x, effective_mass_hole[j], E_l_el_x / ev_in_j, mu_hole_x) + '\n') f.write('{0:^15s}{1:^10s}{2:^15.2f}{3:^15.2f}{4:^15.2f}{5:^17.2f}'. format('Hole', 'y', C_2D_y, effective_mass_hole[j], E_l_el_y / ev_in_j, mu_hole_y) + '\n') # If the temperature range is set if temperature_range: mu_hole_x_list = [ function_cm(t=i, c2d=C_2D_x, el=E_l_hole_x, m=effective_mass_hole[j], md=effective_mass_xy_hole['X']) for i in t_list ] mu_hole_y_list = [ function_cm(t=i, c2d=C_2D_y, el=E_l_hole_y, m=effective_mass_hole[j], md=effective_mass_xy_hole['Y']) for i in t_list ] f1 = open( folder + '/carrier_mobility_t' + str(temperature_range[0]) + '_' + str(temperature_range[1]) + '_hole_VBM_' + j + '_X.out', 'w') for i in range(len(t_list)): f1.write('{0:^15.2f} {1:^15.2f}'.format( t_list[i], mu_hole_x_list[i]) + '\n') f1.close() f1 = open( folder + '/carrier_mobility_t' + str(temperature_range[0]) + '_' + str(temperature_range[1]) + '_hole_VBM_' + j + '_Y.out', 'w') for i in range(len(t_list)): f1.write('{0:^15.2f} {1:^15.2f}'.format( t_list[i], mu_hole_y_list[i]) + '\n') f1.close() # Make figure for the temperature dependence of the carrier mobility of holes plt.plot(t_list, mu_hole_x_list, linewidth=2, linestyle='-', color='red', label='X') plt.plot(t_list, mu_hole_y_list, linewidth=2, linestyle='-', color='blue', label='Y') plt.xlabel('Temperature, K', fontsize=lab_size) plt.ylabel('$\mu_{2D}, cm^2V^{-1}s^{-1}$', fontsize=lab_size) plt.legend(bbox_to_anchor=(0.5, 0.5), borderaxespad=0., labelspacing=0.3, numpoints=1, frameon=True, fancybox=True, markerscale=1., handletextpad=0.3, fontsize=leg_size) plt.title('Hole CBM ->' + j) fig = plt.figure(1) fig.set_figheight(9) fig.set_figwidth(9) fig.savefig( folder + '/carrier_mobility_t' + str(temperature_range[0]) + '_' + str(temperature_range[1]) + '_hole_VBM_' + j + '_XY.pdf', format="pdf", dpi=600) plt.clf() plt.cla() f.close()
def plot_bands(vasprun_dos, vasprun_bands, kpoints, element, ylim = (None, None), folder = '', renew_folder=True, vb_top=0, cb_bottom=1, vbm_pos=0, cbm_pos=0): """ This function is used to build plot of the electronic band structure along with the density of states (DOS) plot. It has feature to provide contributions from different elements to both band structure and DOS. In addition, the band gap (in eV) is automatically calculated. INPUT: - vasprun_dos (str) - path to the vasprun file of the DOS calculation - vasprun_band (str) - path to the vasprun file of the band structure calculation - kpoints (str) - path to the KPOINTS file of the band structure calculation - element (str) - label of the chemical element, for which the contribution to the band structure and DOS - ylim (tuple of floats) - energy range of the band structure and DOS plots, units are eV - folder (str) - directory where all the results will be built - renew_folder (bool) - if True then the folder will be renewed with removing old one - vb_top (int) - number of the last occupied band (valence band) (count starts from '1') - vbm_pos (int) - supposed number of the k-point in the IBZKPT file, at which the valence band maximum (VBM) is located (count starts from '0') - cb_bottom (int) - number of the first unoccupied band (conduction band) (count starts from '1') - cbm_pos (int) - supposed number of the k-point in the IBZKPT file, at which the conduction band minimum (CBM) is located (count starts from '0') RETURN: None SOURCE: Credit https://github.com/gVallverdu/bandstructureplots TODO: Some improvements """ from siman.small_functions import makedir # The folder to collect data necessary for graph building full_name_folder_data = folder+vasprun_bands.split('/')[-2] print('bands.py, string 274, full_name_folder_data ', full_name_folder_data) makedir(full_name_folder_data+'/', renew_folder = renew_folder) labels = read_kpoint_labels(kpoints) # density of states # dosrun = Vasprun(vasprun_dos) dosrun = Vasprun(vasprun_bands) spd_dos = dosrun.complete_dos.get_spd_dos() # bands run = Vasprun(vasprun_bands, parse_projected_eigen=True) bands = run.get_band_structure(kpoints, line_mode=True, efermi=dosrun.efermi) # set up matplotlib plot # ---------------------- # general options for plot font = {'family': 'serif', 'size': 24} plt.rc('font', **font) # set up 2 graph with aspec ration 2/1 # plot 1: bands diagram # plot 2: Density of States gs = GridSpec(1, 2, width_ratios=[2, 1]) fig = plt.figure(figsize=(11.69, 8.27)) # fig.suptitle("Bands diagram of copper") ax1 = plt.subplot(gs[0]) ax2 = plt.subplot(gs[1]) # , sharey=ax1) # set ylim for the plot # --------------------- if ylim[0]: emin = ylim[0] else: emin = -10. if ylim[1]: emax = ylim[1] else: emax = 10. ax1.set_ylim(emin, emax) ax2.set_ylim(emin, emax) # Band Diagram # ------------ name = element pbands = bands.get_projections_on_elements_and_orbitals({name: ["s", "p", "d"]}) # print(pbands) # compute s, p, d normalized contributions contrib = np.zeros((bands.nb_bands, len(bands.kpoints), 3)) for b in range(bands.nb_bands): for k in range(len(bands.kpoints)): sc = pbands[Spin.up][b][k][name]["s"]**2 pc = pbands[Spin.up][b][k][name]["p"]**2 dc = pbands[Spin.up][b][k][name]["d"]**2 tot = sc + pc + dc if tot != 0.0: contrib[b, k, 0] = sc / tot contrib[b, k, 1] = pc / tot contrib[b, k, 2] = dc / tot # plot bands using rgb mapping for b in range(bands.nb_bands): edif = [e - bands.efermi for e in bands.bands[Spin.up][b]] rgbline(ax1, range(len(bands.kpoints)), [e - bands.efermi for e in bands.bands[Spin.up][b]], contrib[b, :, 0], contrib[b, :, 1], contrib[b, :, 2]) f = open(full_name_folder_data+'/band_'+str(b), 'w') for i in range(len(bands.kpoints)): f.write('{0:10d} {1:15.8f}'.format(i, edif[i])+'\n') f.close() f = open(full_name_folder_data+'/band_structure_full', 'w') for j in range(len(bands.kpoints)): s = str(j)+3*' ' for i in range(bands.nb_bands): f1 = open(full_name_folder_data+'/band_'+str(i)) l1 = f1.readlines() f1.close() s += l1[i].rstrip().split()[1]+3*' ' s += '\n' f.write(s) f.close() # Calculating the band gap print('band_'+str(cb_bottom)+'_'+str(cbm_pos), bands.bands[Spin.up][cb_bottom-1][cbm_pos]) print('band_'+str(vb_top)+'_'+str(vbm_pos), bands.bands[Spin.up][vb_top-1][vbm_pos]) print('Eg = ', min(bands.bands[Spin.up][cb_bottom-1])-max(bands.bands[Spin.up][vb_top-1]), 'eV') print('Eg_man = ', bands.bands[Spin.up][cb_bottom-1][cbm_pos]-bands.bands[Spin.up][vb_top-1][vbm_pos], 'eV') print('band_'+str(cb_bottom)+'_min', min(bands.bands[Spin.up][cb_bottom-1])) print('band_'+str(vb_top)+'_max', max(bands.bands[Spin.up][vb_top-1])) print('band_'+str(cb_bottom)+'_min_point', list(bands.bands[Spin.up][cb_bottom-1]).index(min(bands.bands[Spin.up][cb_bottom-1]))) print('band_'+str(vb_top)+'_max_point', list(bands.bands[Spin.up][vb_top-1]).index(max(bands.bands[Spin.up][vb_top-1]))) # style ax1.set_xlabel("k-points") ax1.set_ylabel(r"$E - E_f$ / eV") ax1.grid() # fermi level at 0 ax1.hlines(y=0, xmin=0, xmax=len(bands.kpoints), color="k", linestyle = '--', lw=1) # labels nlabs = len(labels) step = len(bands.kpoints) / (nlabs - 1) for i, lab in enumerate(labels): ax1.vlines(i * step, emin, emax, "k") ax1.set_xticks([i * step for i in range(nlabs)]) ax1.set_xticklabels(labels) ax1.set_xlim(0, len(bands.kpoints)) # Density of states # ---------------- ax2.set_yticklabels([]) ax2.grid() ax2.set_xlim(1e-4, 5) ax2.set_xticklabels([]) ax2.hlines(y=0, xmin=0, xmax=5, color="k", lw=2) ax2.set_xlabel("Density of States", labelpad=28) # spd contribution ax2.plot(spd_dos[OrbitalType.s].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "r-", label="s", lw=2) ax2.plot(spd_dos[OrbitalType.p].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "g-", label="p", lw=2) ax2.plot(spd_dos[OrbitalType.d].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "b-", label="d", lw=2) # total dos ax2.fill_between(dosrun.tdos.densities[Spin.up], 0, dosrun.tdos.energies - dosrun.efermi, color=(0.7, 0.7, 0.7), facecolor=(0.7, 0.7, 0.7)) ax2.plot(dosrun.tdos.densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, color=(0.6, 0.6, 0.6), label="total DOS") edif1 = dosrun.tdos.energies - dosrun.efermi f = open(full_name_folder_data+'/dos_s_'+element, 'w') for i in range(len(spd_dos[OrbitalType.s].densities[Spin.up])): f.write('{0:15.8f} {1:15.8f}'.format(spd_dos[OrbitalType.s].densities[Spin.up][i], edif1[i])+'\n') f.close() f = open(full_name_folder_data+'/dos_p_'+element, 'w') for i in range(len(spd_dos[OrbitalType.p].densities[Spin.up])): f.write('{0:15.8f} {1:15.8f}'.format(spd_dos[OrbitalType.p].densities[Spin.up][i], edif1[i])+'\n') f.close() f = open(full_name_folder_data+'/dos_d_'+element, 'w') for i in range(len(spd_dos[OrbitalType.d].densities[Spin.up])): f.write('{0:15.8f} {1:15.8f}'.format(spd_dos[OrbitalType.d].densities[Spin.up][i], edif1[i])+'\n') f.close() f = open(full_name_folder_data+'/dos_tot', 'w') for i in range(len(dosrun.tdos.densities[Spin.up])): f.write('{0:15.8f} {1:15.8f}'.format(dosrun.tdos.densities[Spin.up][i], edif1[i])+'\n') f.close() # plot format style # ----------------- ax2.legend(fancybox=True, shadow=True, prop={'size': 18}) plt.subplots_adjust(wspace=0) plt.tight_layout() # plt.show() plt.savefig(folder+vasprun_bands.split('/')[-2]+".pdf", format='pdf', dpi=600) # print('bands.efermi ', bands.efermi) # print('dosrun.efermi', dosrun.efermi)
def plot_bands(vasprun_dos, vasprun_bands, kpoints, element, ylim=(None, None), folder='', renew_folder=True, vb_top=0, cb_bottom=1, vbm_pos=0, cbm_pos=0): # read data # --------- # kpoints labels # labels = [r"$L$", r"$\Gamma$", r"$X$", r"$U,K$", r"$\Gamma$"] from functions_system import make_dir as MD # The folder to collect data necessary for graph building full_name_folder_data = folder + vasprun_bands.split('/')[-2] MD(full_name_folder_data, renew_dir=renew_folder) labels = read_kpoint_labels(kpoints) # density of states # dosrun = Vasprun(vasprun_dos) dosrun = Vasprun(vasprun_bands) spd_dos = dosrun.complete_dos.get_spd_dos() # bands run = Vasprun(vasprun_bands, parse_projected_eigen=True) bands = run.get_band_structure(kpoints, line_mode=True, efermi=dosrun.efermi) # set up matplotlib plot # ---------------------- # general options for plot font = {'family': 'serif', 'size': 24} plt.rc('font', **font) # set up 2 graph with aspec ration 2/1 # plot 1: bands diagram # plot 2: Density of States gs = GridSpec(1, 2, width_ratios=[2, 1]) fig = plt.figure(figsize=(11.69, 8.27)) # fig.suptitle("Bands diagram of copper") ax1 = plt.subplot(gs[0]) ax2 = plt.subplot(gs[1]) # , sharey=ax1) # set ylim for the plot # --------------------- if ylim[0]: emin = ylim[0] else: emin = -10. if ylim[1]: emax = ylim[1] else: emax = 10. ax1.set_ylim(emin, emax) ax2.set_ylim(emin, emax) # Band Diagram # ------------ name = element pbands = bands.get_projections_on_elements_and_orbitals( {name: ["s", "p", "d"]}) # print(pbands) # compute s, p, d normalized contributions contrib = np.zeros((bands.nb_bands, len(bands.kpoints), 3)) for b in range(bands.nb_bands): for k in range(len(bands.kpoints)): sc = pbands[Spin.up][b][k][name]["s"]**2 pc = pbands[Spin.up][b][k][name]["p"]**2 dc = pbands[Spin.up][b][k][name]["d"]**2 tot = sc + pc + dc if tot != 0.0: contrib[b, k, 0] = sc / tot contrib[b, k, 1] = pc / tot contrib[b, k, 2] = dc / tot # plot bands using rgb mapping for b in range(bands.nb_bands): edif = [e - bands.efermi for e in bands.bands[Spin.up][b]] rgbline(ax1, range(len(bands.kpoints)), [e - bands.efermi for e in bands.bands[Spin.up][b]], contrib[b, :, 0], contrib[b, :, 1], contrib[b, :, 2]) f = open(full_name_folder_data + '/band_' + str(b), 'w') for i in range(len(bands.kpoints)): f.write('{0:10d} {1:15.8f}'.format(i, edif[i]) + '\n') f.close() f = open(full_name_folder_data + '/band_structure_full', 'w') for j in range(len(bands.kpoints)): s = str(j) + 3 * ' ' for i in range(bands.nb_bands): f1 = open(full_name_folder_data + '/band_' + str(i)) l1 = f1.readlines() f1.close() s += l1[i].rstrip().split()[1] + 3 * ' ' s += '\n' f.write(s) f.close() # Calculating the band gap print('band_' + str(cb_bottom) + '_' + str(cbm_pos), bands.bands[Spin.up][cb_bottom - 1][cbm_pos]) print('band_' + str(vb_top) + '_' + str(vbm_pos), bands.bands[Spin.up][vb_top - 1][vbm_pos]) print( 'Eg = ', min(bands.bands[Spin.up][cb_bottom - 1]) - max(bands.bands[Spin.up][vb_top - 1]), 'eV') print( 'Eg_man = ', bands.bands[Spin.up][cb_bottom - 1][cbm_pos] - bands.bands[Spin.up][vb_top - 1][vbm_pos], 'eV') print('band_' + str(cb_bottom) + '_min', min(bands.bands[Spin.up][cb_bottom - 1])) print('band_' + str(vb_top) + '_max', max(bands.bands[Spin.up][vb_top - 1])) print( 'band_' + str(cb_bottom) + '_min_point', list(bands.bands[Spin.up][cb_bottom - 1]).index( min(bands.bands[Spin.up][cb_bottom - 1]))) print( 'band_' + str(vb_top) + '_max_point', list(bands.bands[Spin.up][vb_top - 1]).index( max(bands.bands[Spin.up][vb_top - 1]))) # style ax1.set_xlabel("k-points") ax1.set_ylabel(r"$E - E_f$ / eV") ax1.grid() # fermi level at 0 ax1.hlines(y=0, xmin=0, xmax=len(bands.kpoints), color="k", linestyle='--', lw=1) # labels nlabs = len(labels) step = len(bands.kpoints) / (nlabs - 1) for i, lab in enumerate(labels): ax1.vlines(i * step, emin, emax, "k") ax1.set_xticks([i * step for i in range(nlabs)]) ax1.set_xticklabels(labels) ax1.set_xlim(0, len(bands.kpoints)) # Density of states # ---------------- ax2.set_yticklabels([]) ax2.grid() ax2.set_xlim(1e-4, 5) ax2.set_xticklabels([]) ax2.hlines(y=0, xmin=0, xmax=5, color="k", lw=2) ax2.set_xlabel("Density of States", labelpad=28) # spd contribution ax2.plot(spd_dos[OrbitalType.s].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "r-", label="s", lw=2) ax2.plot(spd_dos[OrbitalType.p].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "g-", label="p", lw=2) ax2.plot(spd_dos[OrbitalType.d].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "b-", label="d", lw=2) # total dos ax2.fill_between(dosrun.tdos.densities[Spin.up], 0, dosrun.tdos.energies - dosrun.efermi, color=(0.7, 0.7, 0.7), facecolor=(0.7, 0.7, 0.7)) ax2.plot(dosrun.tdos.densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, color=(0.6, 0.6, 0.6), label="total DOS") edif1 = dosrun.tdos.energies - dosrun.efermi f = open(full_name_folder_data + '/dos_s_' + element, 'w') for i in range(len(spd_dos[OrbitalType.s].densities[Spin.up])): f.write('{0:15.8f} {1:15.8f}'.format( spd_dos[OrbitalType.s].densities[Spin.up][i], edif1[i]) + '\n') f.close() f = open(full_name_folder_data + '/dos_p_' + element, 'w') for i in range(len(spd_dos[OrbitalType.p].densities[Spin.up])): f.write('{0:15.8f} {1:15.8f}'.format( spd_dos[OrbitalType.p].densities[Spin.up][i], edif1[i]) + '\n') f.close() f = open(full_name_folder_data + '/dos_d_' + element, 'w') for i in range(len(spd_dos[OrbitalType.d].densities[Spin.up])): f.write('{0:15.8f} {1:15.8f}'.format( spd_dos[OrbitalType.d].densities[Spin.up][i], edif1[i]) + '\n') f.close() f = open(full_name_folder_data + '/dos_tot', 'w') for i in range(len(dosrun.tdos.densities[Spin.up])): f.write('{0:15.8f} {1:15.8f}'.format(dosrun.tdos.densities[Spin.up][i], edif1[i]) + '\n') f.close() # plot format style # ----------------- ax2.legend(fancybox=True, shadow=True, prop={'size': 18}) plt.subplots_adjust(wspace=0) plt.tight_layout() # plt.show() plt.savefig(folder + vasprun_bands.split('/')[-2] + ".pdf", format='pdf', dpi=600)