def _get_fd(energy, fermi_levels, temperatures): f = np.zeros(fermi_levels.shape) for n, t in np.ndindex(fermi_levels.shape): f[n, t] = fd(energy, fermi_levels[n, t], temperatures[t] * boltzmann_au) return f
def _get_weighted_dos(energies, dos, fermi_level, temperature, atomic_units=True): if temperature == 0.0: occ = np.where(energies < fermi_level, 1.0, 0.0) occ[energies == fermi_level] = 0.5 else: kbt = temperature * boltzmann_au if atomic_units: occ = fd(energies, fermi_level, kbt) else: occ = fd(energies * ev_to_hartree, fermi_level * ev_to_hartree, kbt) wdos = dos * occ return wdos
def _get_fd(energy, amset_data): f = np.zeros(amset_data.fermi_levels.shape) for n, t in np.ndindex(amset_data.fermi_levels.shape): f[n, t] = fd( energy, amset_data.fermi_levels[n, t], amset_data.temperatures[t] * boltzmann_au, ) return f
def fermiintegrals(epsilon, dos, sigma, mur, Tr, dosweight=2.0, cdos=None): """Compute the moments of the FD distribution over the band structure. Args: epsilon: array of energies at which the DOS is available dos: density of states sigma: transport DOS mur: array of chemical potential values Tr: array of temperature values dosweight: maximum occupancy of an electron mode cdos: "curvature DOS" if available Returns: Five numpy arrays, namely: 1. An (nT, nmu) array with the electron counts for each temperature and each chemical potential. 2. An (nT, nmu, 3, 3) with the integrals of the 3 x 3 transport DOS over the band structure taking the occupancies into account. 3. An (nT, nmu, 3, 3) with the first moment of the 3 x 3 transport DOS over the band structure taking the occupancies into account. 4. An (nT, nmu, 3, 3) with the second moment of the 3 x 3 transport DOS over the band structure taking the occupancies into account. 5. If the cdos argument is provided, an (nT, nmu, 3, 3, 3) with the integrals of the 3 x 3 x 3 "curvature DOS" over the band structure taking the occupancies into account. where nT and nmu are the sizes of Tr and mur, respectively. """ kBTr = np.array(Tr) * BOLTZMANN nT = len(Tr) nmu = len(mur) N = np.empty((nT, nmu)) L0 = np.empty((nT, nmu, 3, 3)) L1 = np.empty((nT, nmu, 3, 3)) L2 = np.empty((nT, nmu, 3, 3)) if cdos is not None: L11 = np.empty((nT, nmu, 3, 3, 3)) else: L11 = None de = epsilon[1] - epsilon[0] for iT, kBT in enumerate(kBTr): for imu, mu in enumerate(mur): N[iT, imu] = -(dosweight * dos * fd(epsilon, mu, kBT)).sum() * de int0 = -dosweight * dfdde(epsilon, mu, kBT) intn = int0 * sigma L0[iT, imu] = intn.sum(axis=2) * de intn *= epsilon - mu L1[iT, imu] = -intn.sum(axis=2) * de intn *= epsilon - mu L2[iT, imu] = intn.sum(axis=2) * de if cdos is not None: cint = int0 * cdos L11[iT, imu] = -cint.sum(axis=3) * de return N, L0, L1, L2, L11
def calculate_inverse_screening_length_sq(amset_data, dielectric): inverse_screening_length_sq = np.zeros(amset_data.fermi_levels.shape) tdos = amset_data.dos.tdos energies = amset_data.dos.energies fermi_levels = amset_data.fermi_levels vol = amset_data.structure.volume for n, t in np.ndindex(inverse_screening_length_sq.shape): ef = fermi_levels[n, t] temp = amset_data.temperatures[t] f = fd(energies, ef, temp * boltzmann_au) integral = np.trapz(tdos * f * (1 - f), x=energies) inverse_screening_length_sq[n, t] = ( integral * 4 * np.pi / (dielectric * boltzmann_au * temp * vol)) return inverse_screening_length_sq