def _log_band_structure_information(band_structure: BandStructure): log_banner("BAND STRUCTURE") info = [ "# bands: {}".format(band_structure.nb_bands), "# k-points: {}".format(len(band_structure.kpoints)), "Fermi level: {:.3f} eV".format(band_structure.efermi), "spin polarized: {}".format(band_structure.is_spin_polarized), "metallic: {}".format(band_structure.is_metal()), ] logger.info("Input band structure information:") log_list(info) if band_structure.is_metal(): return logger.info("Band gap:") band_gap_info = [] bg_data = band_structure.get_band_gap() if not bg_data["direct"]: band_gap_info.append("indirect band gap: {:.3f} eV".format( bg_data["energy"])) direct_data = band_structure.get_direct_band_gap_dict() direct_bg = min((spin_data["value"] for spin_data in direct_data.values())) band_gap_info.append("direct band gap: {:.3f} eV".format(direct_bg)) direct_kpoint = [] for spin, spin_data in direct_data.items(): direct_kindex = spin_data["kpoint_index"] kpt_str = _kpt_str.format( k=band_structure.kpoints[direct_kindex].frac_coords) direct_kpoint.append(kpt_str) band_gap_info.append("direct k-point: {}".format(", ".join(direct_kpoint))) log_list(band_gap_info) vbm_data = band_structure.get_vbm() cbm_data = band_structure.get_cbm() logger.info("Valence band maximum:") _log_band_edge_information(band_structure, vbm_data) logger.info("Conduction band minimum:") _log_band_edge_information(band_structure, cbm_data)
def get_energy_cutoffs( energy_cutoff: float, band_structure: BandStructure ) -> Tuple[float, float]: if energy_cutoff and band_structure.is_metal(): min_e = band_structure.efermi - energy_cutoff max_e = band_structure.efermi + energy_cutoff elif energy_cutoff: min_e = band_structure.get_vbm()["energy"] - energy_cutoff max_e = band_structure.get_cbm()["energy"] + energy_cutoff else: min_e = min( [band_structure.bands[spin].min() for spin in band_structure.bands.keys()] ) max_e = max( [band_structure.bands[spin].max() for spin in band_structure.bands.keys()] ) return min_e, max_e
def get_vb_idx(energy_cutoff: float, band_structure: BandStructure): if band_structure.is_metal(): return None ibands = get_ibands(energy_cutoff, band_structure, return_idx=False) new_vb_idx = {} for spin, bands in band_structure.bands.items(): spin_ibands = ibands[spin] # valence bands are all bands that contain energies less than efermi vbs = (bands < band_structure.efermi).any(axis=1) vb_idx = np.where(vbs)[0].max() # need to know the index of the valence band after discounting # bands during the interpolation. As ibands is just a list of # True/False, we can count the number of Trues included up to # and including the VBM to get the new number of valence bands new_vb_idx[spin] = sum(spin_ibands[: vb_idx + 1]) - 1 return new_vb_idx