Ejemplo n.º 1
0
    def compute_properties_doping(self, doping, temp_r=None):
        """
        Calculate all the properties w.r.t. the doping levels in input.

        Args:
            doping: numpy array specifying the doping levels

        When executed, it add the following variable at the BztTransportProperties
        object:
            Conductivity_doping, Seebeck_doping, Kappa_doping, Power_Factor_doping,
            cond_Effective_mass_doping are dictionaries with 'n' and 'p' keys and
            arrays of dim (len(temp_r),len(doping),3,3) as values.
            Carriers_conc_doping: carriers concentration for each doping level and T.
            mu_doping_eV: the chemical potential corrispondent to each doping level.
        """

        if temp_r is None:
            temp_r = self.temp_r

        (
            self.Conductivity_doping,
            self.Seebeck_doping,
            self.Kappa_doping,
            self.Carriers_conc_doping,
        ) = ({}, {}, {}, {})

        self.Power_Factor_doping, self.Effective_mass_doping = {}, {}

        mu_doping = {}
        doping_carriers = [
            dop * (self.volume / (units.Meter / 100.0)**3) for dop in doping
        ]

        for dop_type in ["n", "p"]:
            sbk = np.zeros((len(temp_r), len(doping), 3, 3))
            cond = np.zeros((len(temp_r), len(doping), 3, 3))
            kappa = np.zeros((len(temp_r), len(doping), 3, 3))
            hall = np.zeros((len(temp_r), len(doping), 3, 3, 3))
            dc = np.zeros((len(temp_r), len(doping)))

            if dop_type == "p":
                doping_carriers = [-dop for dop in doping_carriers]

            mu_doping[dop_type] = np.zeros((len(temp_r), len(doping)))
            for t, temp in enumerate(temp_r):
                for i, dop_car in enumerate(doping_carriers):
                    mu_doping[dop_type][t, i] = BL.solve_for_mu(
                        self.epsilon,
                        self.dos,
                        self.nelect + dop_car,
                        temp,
                        self.dosweight,
                        True,
                        False,
                    )
                    # mu_doping[dop_type][t, i] = self.find_mu_doping(
                    #     self.epsilon, self.dos, self.nelect + dop_car, temp,
                    #     self.dosweight)

                N, L0, L1, L2, Lm11 = BL.fermiintegrals(
                    self.epsilon,
                    self.dos,
                    self.vvdos,
                    mur=mu_doping[dop_type][t],
                    Tr=np.array([temp]),
                    dosweight=self.dosweight,
                )

                cond[t], sbk[t], kappa[t], hall[
                    t] = BL.calc_Onsager_coefficients(
                        L0,
                        L1,
                        L2,
                        mu_doping[dop_type][t],
                        np.array([temp]),
                        self.volume,
                        Lm11,
                    )

                dc[t] = self.nelect + N

            self.Conductivity_doping[dop_type] = cond * self.CRTA  # S / m
            self.Seebeck_doping[dop_type] = sbk * 1e6  # microVolt / K
            self.Kappa_doping[dop_type] = kappa * self.CRTA  # W / (m K)
            # self.Hall_doping[dop_type] = hall
            self.Carriers_conc_doping[dop_type] = dc / (
                self.volume / (units.Meter / 100.0)**3)

            self.Power_Factor_doping[dop_type] = (
                sbk @ sbk) @ cond * self.CRTA * 1e3

            cond_eff_mass = np.zeros((len(temp_r), len(doping), 3, 3))
            for t in range(len(temp_r)):
                for i, dop in enumerate(doping):
                    try:
                        cond_eff_mass[t, i] = np.linalg.inv(
                            cond[t,
                                 i]) * dop * units.qe_SI**2 / units.me_SI * 1e6
                    except np.linalg.LinAlgError:
                        pass

            self.Effective_mass_doping[dop_type] = cond_eff_mass

        self.doping = doping
        self.mu_doping = mu_doping
        self.mu_doping_eV = {
            k: v / units.eV - self.efermi
            for k, v in mu_doping.items()
        }
        self.contain_props_doping = True
Ejemplo n.º 2
0
    erange=[data.fermi - ecut, data.fermi + ecut],
    npts=round(2 * ecut / deltae),
    scattering_model='uniform_tau')

# Define the temperatures and chemical potentials we are interested in
#Tr = np.arange(deltat, tmax + deltat / 2, deltat)
#mur_indices = np.logical_and(epsilon > data.fermi - efcut, epsilon < data.fermi + efcut)
#mur = epsilon[mur_indices]

Tr = np.arange(deltat, tmax + deltat / 2, deltat)
mur = np.empty_like(Tr)
_nelect = data.nelect
for iT, T in enumerate(Tr):
    mur[iT] = BL.solve_for_mu(epsilon,
                              dos,
                              _nelect - doping_level,
                              T,
                              data.dosweight,
                              refine=True)

    # The flow from this point is again similar to that in parse_integrate,
    # with the exception that the chemical potentials are different for
    # each temperature.

N = np.empty_like(Tr)
L0, L1, L2 = (np.empty((Tr.shape[0], 3, 3)) for ii in range(3))
Lm11 = np.empty((Tr.shape[0], 3, 3, 3))
# Obtain the Fermi integrals required to get the Onsager coefficients
for iT, T in enumerate(Tr):
    (N[iT], L0[iT], L1[iT], L2[iT],
     Lm11[iT]) = BL.fermiintegrals(epsilon,
                                   dos,
Ejemplo n.º 3
0
def boltztrap(dirname, bt2file, title, T):
    print(("\n\nWorking in %s for %s at %i K" % (dirname, title, T)))
    # If a ready-made file with the interpolation results is available, use it
    # Otherwise, create the file.
    if not os.path.exists(bt2file):
        # Load the input
        data = BTP.DFTData(dirname)
        # Select the interesting bands
        nemin, nemax = data.bandana(emin=data.fermi - .2, emax=data.fermi + .2)
        # Set up a k point grid with roughly five times the density of the input
        equivalences = sphere.get_equivalences(data.atoms,
                                               len(data.kpoints) * 5)
        # Perform the interpolation
        coeffs = fite.fitde3D(data, equivalences)
        # Save the result
        serialization.save_calculation(
            bt2file, data, equivalences, coeffs,
            serialization.gen_bt2_metadata(data, data.mommat is not None))

    # Load the interpolation results
    print("Load the interpolation results")
    data, equivalences, coeffs, metadata = serialization.load_calculation(
        bt2file)

    # Reconstruct the bands
    print("Reconstruct the bands")
    lattvec = data.get_lattvec()
    eband, vvband, cband = fite.getBTPbands(equivalences, coeffs, lattvec)

    # Obtain the Fermi integrals for different chemical potentials at
    # room temperature.
    TEMP = np.array([T])
    epsilon, dos, vvdos, cdos = BL.BTPDOS(eband, vvband, npts=4000)
    margin = 9. * units.BOLTZMANN * TEMP.max()
    mur_indices = np.logical_and(epsilon > epsilon.min() + margin,
                                 epsilon < epsilon.max() - margin)
    mur = epsilon[mur_indices]
    N, L0, L1, L2, Lm11 = BL.fermiintegrals(epsilon,
                                            dos,
                                            vvdos,
                                            mur=mur,
                                            Tr=TEMP,
                                            dosweight=data.dosweight)

    # Compute the Onsager coefficients from those Fermi integrals
    print("Compute the Onsager coefficients")
    UCvol = data.get_volume()
    sigma, seebeck, kappa, Hall = BL.calc_Onsager_coefficients(
        L0, L1, L2, mur, TEMP, UCvol)

    fermi = BL.solve_for_mu(epsilon, dos, data.nelect, T, data.dosweight)

    savedata[title + '-%s' % T] = {
        "sigma": sigma,
        "seebeck": seebeck,
        "kappa": kappa,
        "Hall": Hall,
        "mu": (mur - fermi) / BL.eV,
        "temp": T,
        "n": N[0] + data.nelect
    }
Ejemplo n.º 4
0
mur_indices = np.logical_and(epsilon > epsilon.min() + margin,
                             epsilon < epsilon.max() - margin)
mur = epsilon[mur_indices]
N, L0, L1, L2, Lm11 = BL.fermiintegrals(epsilon,
                                        dos,
                                        vvdos,
                                        mur=mur,
                                        Tr=TEMP,
                                        dosweight=data.dosweight)

# Compute the Onsager coefficients from those Fermi integrals
UCvol = data.get_volume()
sigma, seebeck, kappa, Hall = BL.calc_Onsager_coefficients(
    L0, L1, L2, mur, TEMP, UCvol)

fermi = BL.solve_for_mu(epsilon, dos, data.nelect, 300, data.dosweight)

# Plot the results
fig1, ax1 = pl.subplots(1, figsize=(6, 3))
ax1.set_xlim([-1, 1])
ax1.set_ylim([-300, 300])
ax1.plot((mur - fermi) / BL.eV,
         seebeck[0, :, 0, 0] * 1e6,
         "k-",
         label="xx \n seebeck[0, 0:0, 0, 0] * 1e6")
ax1.plot((mur - fermi) / BL.eV, seebeck[0, :, 2, 2] * 1e6, "k--", label="zz")
ax1.set_xlabel("$\mu$ [eV]")
ax1.set_ylabel("$S$ [$\mu$V/K]")
ax1.legend()
fig1.tight_layout(pad=1.)
fig1.savefig("seebeck.pdf")