Exemplo n.º 1
0
    def get_dos(self, partial_dos=False, npts_mu=10000, T=None):
        """
            Return a Dos object interpolating bands

            Args:
                partial_dos: if True, projections will be interpolated as well
                    and partial doses will be return. Projections must be available
                    in the loader.
                npts_mu: number of energy points of the Dos
                T: parameter used to smooth the Dos
        """
        spin = self.data.spin if isinstance(self.data.spin, int) else 1

        energies, densities, vvdos, cdos = BL.BTPDOS(self.eband,
                                                     self.vvband,
                                                     npts=npts_mu)
        if T is not None:
            densities = BL.smoothen_DOS(energies, densities, T)

        tdos = Dos(self.efermi / units.eV, energies / units.eV,
                   {Spin(spin): densities})

        if partial_dos:
            tdos = self.get_partial_doses(tdos=tdos, npts_mu=npts_mu, T=T)

        return tdos
Exemplo n.º 2
0
    def __init__(self, BztInterpolator, temp_r=np.arange(100, 1400, 100),
                 doping=10. ** np.arange(16, 23), npts_mu=4000, CRTA=1e-14, margin=None):

        self.CRTA = CRTA
        self.temp_r = temp_r
        self.doping = doping
        self.dosweight = BztInterpolator.data.dosweight
        lattvec = BztInterpolator.data.get_lattvec()

        self.epsilon, self.dos, self.vvdos, self.cdos = BL.BTPDOS(BztInterpolator.eband, BztInterpolator.vvband,
                                                                  npts=npts_mu, cband=BztInterpolator.cband)

        if margin is None:
            margin = 9. * units.BOLTZMANN * temp_r.max()

        mur_indices = np.logical_and(self.epsilon > self.epsilon.min() + margin,
                                     self.epsilon < self.epsilon.max() - margin)

        self.mu_r = self.epsilon[mur_indices]

        N, L0, L1, L2, Lm11 = BL.fermiintegrals(
            self.epsilon, self.dos, self.vvdos, mur=self.mu_r, Tr=temp_r, dosweight=self.dosweight, cdos=self.cdos)

        self.efermi = BztInterpolator.data.fermi / units.eV
        self.mu_r_eV = self.mu_r / units.eV - self.efermi
        self.nelect = BztInterpolator.data.nelect
        self.volume = BztInterpolator.data.get_volume()

        # Compute the Onsager coefficients from those Fermi integrals
        self.Conductivity_mu, self.Seebeck_mu, self.Kappa_mu, Hall_mu = BL.calc_Onsager_coefficients(L0, L1, L2,
                                                                                                     self.mu_r, temp_r,
                                                                                                     self.volume,
                                                                                                     Lm11=Lm11)

        # Common properties rescaling
        self.Conductivity_mu *= CRTA  # S / m
        self.Seebeck_mu *= 1e6  # microvolt / K
        self.Kappa_mu *= CRTA  # W / (m K)
        self.Hall_carrier_conc_trace_mu = units.Coulomb * 1e-6 / (np.abs(Hall_mu[:, :, 0, 1, 2] +
                                                                         Hall_mu[:, :, 2, 0, 1] +
                                                                         Hall_mu[:, :, 1, 2, 0]) / 3)
        self.Carrier_conc_mu = (N + self.nelect) / (self.volume / (units.Meter / 100.) ** 3)

        # Derived properties
        cond_eff_mass = np.zeros((len(self.temp_r), len(self.mu_r), 3, 3))
        for t in range(len(self.temp_r)):
            for i in range(len(self.mu_r)):
                try:
                    cond_eff_mass[t, i] = np.linalg.inv(self.Conductivity_mu[t, i]) * self.Carrier_conc_mu[
                        t, i] * units.qe_SI ** 2 / units.me_SI * 1e6
                except np.linalg.LinAlgError:
                    pass

        self.Effective_mass_mu = cond_eff_mass * CRTA

        self.Power_Factor_mu = (self.Seebeck_mu @ self.Seebeck_mu) @ self.Conductivity_mu
        self.Power_Factor_mu *= 1e-9  # milliWatt / m / K**2
Exemplo n.º 3
0
    def get_dos(self,
                partial_dos=False,
                npts_mu=10000,
                T=None,
                progress=False):
        """
        Return a Dos object interpolating bands

        Args:
            partial_dos: if True, projections will be interpolated as well
                and partial doses will be return. Projections must be available
                in the loader.
            npts_mu: number of energy points of the Dos
            T: parameter used to smooth the Dos
            progress: Default False, If True a progress bar is shown when
                partial dos are computed.
        """
        dos_dict = {}
        enr = (self.eband.min(), self.eband.max())
        if self.data.is_spin_polarized:
            h = sum(np.array_split(self.accepted, 2)[0])
            eband_ud = np.array_split(self.eband, [h], axis=0)
            vvband_ud = np.array_split(self.vvband, [h], axis=0)
            spins = [Spin.up, Spin.down]
        else:
            eband_ud = [self.eband]
            vvband_ud = [self.vvband]
            spins = [Spin.up]

        for spin, eb, vvb in zip(spins, eband_ud, vvband_ud):
            energies, densities, vvdos, cdos = BL.BTPDOS(eb,
                                                         vvb,
                                                         npts=npts_mu,
                                                         erange=enr)

            if T:
                densities = BL.smoothen_DOS(energies, densities, T)

            dos_dict.setdefault(spin, densities)

        tdos = Dos(self.efermi / units.eV, energies / units.eV, dos_dict)

        if partial_dos:
            tdos = self.get_partial_doses(tdos, eband_ud, spins, enr, npts_mu,
                                          T, progress)

        return tdos
Exemplo n.º 4
0
    def __init__(
        self,
        BztInterpolator,
        temp_r=np.arange(100, 1400, 100),
        doping=None,
        npts_mu=4000,
        CRTA=1e-14,
        margin=None,
        save_bztTranspProps=False,
        load_bztTranspProps=False,
        fname="bztTranspProps.json.gz",
    ):
        """
        Args:
            BztInterpolator: a BztInterpolator previously generated
            temp_r: numpy array of temperatures at which to calculate transport properties
            doping: doping levels at which to calculate transport properties. If provided,
                transport properties w.r.t. these doping levels are also computed. See
                compute_properties_doping() method for details.
            npts_mu: number of energy points at which to calculate transport properties
            CRTA: constant value of the relaxation time
            save_bztTranspProps: Default False. If True all computed transport properties
                will be stored in fname file.
            load_bztTranspProps: Default False. If True all computed transport properties
                will be loaded from fname file.
            fname: File path where to save/load transport properties.

        Upon creation, it contains properties tensors w.r.t. the chemical potential
        of size (len(temp_r),npts_mu,3,3):
            Conductivity_mu (S/m), Seebeck_mu (microV/K), Kappa_mu (W/(m*K)),
            Power_Factor_mu (milliW/K m);
            cond_Effective_mass_mu (m_e) calculated as Ref.
        Also:
            Carrier_conc_mu: carrier concentration of size (len(temp_r),npts_mu)
            Hall_carrier_conc_trace_mu: trace of Hall carrier concentration of size
                (len(temp_r),npts_mu)
            mu_r_eV: array of energies in eV and with E_fermi at 0.0
                where all the properties are calculated.

        Example:
            bztTransp = BztTransportProperties(bztInterp,temp_r = np.arange(100,1400,100))
        """

        self.dosweight = BztInterpolator.data.dosweight
        self.volume = BztInterpolator.data.get_volume()
        self.nelect = BztInterpolator.data.nelect
        self.efermi = BztInterpolator.data.fermi / units.eV

        if margin is None:
            margin = 9.0 * units.BOLTZMANN * temp_r.max()

        if load_bztTranspProps:
            self.load(fname)
        else:
            self.CRTA = CRTA
            self.temp_r = temp_r
            self.doping = doping

            self.epsilon, self.dos, self.vvdos, self.cdos = BL.BTPDOS(
                BztInterpolator.eband,
                BztInterpolator.vvband,
                npts=npts_mu,
                cband=BztInterpolator.cband,
            )

            mur_indices = np.logical_and(
                self.epsilon > self.epsilon.min() + margin,
                self.epsilon < self.epsilon.max() - margin,
            )

            self.mu_r = self.epsilon[mur_indices]
            self.mu_r_eV = self.mu_r / units.eV - self.efermi

            N, L0, L1, L2, Lm11 = BL.fermiintegrals(
                self.epsilon,
                self.dos,
                self.vvdos,
                mur=self.mu_r,
                Tr=temp_r,
                dosweight=self.dosweight,
                cdos=self.cdos,
            )

            # Compute the Onsager coefficients from those Fermi integrals
            (
                self.Conductivity_mu,
                self.Seebeck_mu,
                self.Kappa_mu,
                Hall_mu,
            ) = BL.calc_Onsager_coefficients(L0,
                                             L1,
                                             L2,
                                             self.mu_r,
                                             temp_r,
                                             self.volume,
                                             Lm11=Lm11)

            # Common properties rescaling
            self.Conductivity_mu *= CRTA  # S / m
            self.Seebeck_mu *= 1e6  # microvolt / K
            self.Kappa_mu *= CRTA  # W / (m K)
            self.Hall_carrier_conc_trace_mu = (
                units.Coulomb * 1e-6 /
                (np.abs(Hall_mu[:, :, 0, 1, 2] + Hall_mu[:, :, 2, 0, 1] +
                        Hall_mu[:, :, 1, 2, 0]) / 3))
            self.Carrier_conc_mu = (N +
                                    self.nelect) / (self.volume /
                                                    (units.Meter / 100.0)**3)

            # Derived properties
            cond_eff_mass = np.zeros((len(self.temp_r), len(self.mu_r), 3, 3))
            for t in range(len(self.temp_r)):
                for i in range(len(self.mu_r)):
                    try:
                        cond_eff_mass[t, i] = (
                            np.linalg.inv(self.Conductivity_mu[t, i]) *
                            self.Carrier_conc_mu[t, i] * units.qe_SI**2 /
                            units.me_SI * 1e6)
                    except np.linalg.LinAlgError:
                        pass

            self.Effective_mass_mu = cond_eff_mass * CRTA

            self.Power_Factor_mu = (
                self.Seebeck_mu @ self.Seebeck_mu) @ self.Conductivity_mu
            self.Power_Factor_mu *= 1e-9  # milliWatt / m / K**2

            # self.props_as_dict()

            self.contain_props_doping = False

            if isinstance(doping, np.ndarray):
                self.compute_properties_doping(doping, temp_r)

            if save_bztTranspProps:
                self.save(fname)
Exemplo n.º 5
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
    }
Exemplo n.º 6
0
ecut, efcut, deltae, tmax, deltat, lpfac = 1.0 * RYDBERG, 0.3 * RYDBERG, 0.0005 * RYDBERG, 1200.0, 10.0, 5

# Load the input
data = dft.DFTData(dirname)
# Select the interesting bands
nemin, nemax = data.bandana(emin=data.fermi - ecut, emax=data.fermi + ecut)
# Set up a k point grid with roughly five times the density of the input
equivalences = sphere.get_equivalences(data.atoms, len(data.kpoints) * lpfac)
# Perform the interpolation
coeffs = fite.fitde3D(data, equivalences)

lattvec = data.get_lattvec()
eband, vvband, cband = fite.getBTPbands(equivalences, coeffs, lattvec)
epsilon, dos, vvdos, cdos = BL.BTPDOS(
    eband,
    vvband,
    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,
Exemplo n.º 7
0
    def __init__(self,
                 BztInterpolator,
                 temp_r=np.arange(100, 1400, 100),
                 doping=10.**np.arange(16, 23),
                 npts_mu=4000,
                 CRTA=1e-14,
                 margin=None):
        """
        Args:
            BztInterpolator: a BztInterpolator previously generated
            temp_r: numpy array of temperatures at which to calculate trasport properties
            doping: doping levels at which to calculate trasport properties
            npts_mu: number of energy points at which to calculate trasport properties
            CRTA: constant value of the relaxation time

        Upon creation, it contains properties tensors w.r.t. the chemical potential
        of size (len(temp_r),npts_mu,3,3):
            Conductivity_mu (S/m), Seebeck_mu (microV/K), Kappa_mu (W/(m*K)),
            Power_Factor_mu (milliW/K);
            cond_Effective_mass_mu (m_e) calculated as Ref.
        Also:
            Carrier_conc_mu: carrier concentration of size (len(temp_r),npts_mu)
            Hall_carrier_conc_trace_mu: trace of Hall carrier concentration of size
                (len(temp_r),npts_mu)
            mu_r_eV: array of energies in eV and with E_fermi at 0.0
                where all the properties are calculated.

        Example:
            bztTransp = BztTransportProperties(bztInterp,temp_r = np.arange(100,1400,100))
        """

        self.CRTA = CRTA
        self.temp_r = temp_r
        self.doping = doping
        self.dosweight = BztInterpolator.data.dosweight

        self.epsilon, self.dos, self.vvdos, self.cdos = BL.BTPDOS(
            BztInterpolator.eband,
            BztInterpolator.vvband,
            npts=npts_mu,
            cband=BztInterpolator.cband)

        if margin is None:
            margin = 9. * units.BOLTZMANN * temp_r.max()

        mur_indices = np.logical_and(
            self.epsilon > self.epsilon.min() + margin,
            self.epsilon < self.epsilon.max() - margin)

        self.mu_r = self.epsilon[mur_indices]

        N, L0, L1, L2, Lm11 = BL.fermiintegrals(self.epsilon,
                                                self.dos,
                                                self.vvdos,
                                                mur=self.mu_r,
                                                Tr=temp_r,
                                                dosweight=self.dosweight,
                                                cdos=self.cdos)

        self.efermi = BztInterpolator.data.fermi / units.eV
        self.mu_r_eV = self.mu_r / units.eV - self.efermi
        self.nelect = BztInterpolator.data.nelect
        self.volume = BztInterpolator.data.get_volume()

        # Compute the Onsager coefficients from those Fermi integrals
        self.Conductivity_mu, self.Seebeck_mu, self.Kappa_mu, Hall_mu = BL.calc_Onsager_coefficients(
            L0, L1, L2, self.mu_r, temp_r, self.volume, Lm11=Lm11)

        # Common properties rescaling
        self.Conductivity_mu *= CRTA  # S / m
        self.Seebeck_mu *= 1e6  # microvolt / K
        self.Kappa_mu *= CRTA  # W / (m K)
        self.Hall_carrier_conc_trace_mu = units.Coulomb * 1e-6 / (
            np.abs(Hall_mu[:, :, 0, 1, 2] + Hall_mu[:, :, 2, 0, 1] +
                   Hall_mu[:, :, 1, 2, 0]) / 3)
        self.Carrier_conc_mu = (N + self.nelect) / (self.volume /
                                                    (units.Meter / 100.)**3)

        # Derived properties
        cond_eff_mass = np.zeros((len(self.temp_r), len(self.mu_r), 3, 3))
        for t in range(len(self.temp_r)):
            for i in range(len(self.mu_r)):
                try:
                    cond_eff_mass[t, i] = np.linalg.inv(
                        self.Conductivity_mu[t, i]) * self.Carrier_conc_mu[
                            t, i] * units.qe_SI**2 / units.me_SI * 1e6
                except np.linalg.LinAlgError:
                    pass

        self.Effective_mass_mu = cond_eff_mass * CRTA

        self.Power_Factor_mu = (
            self.Seebeck_mu @ self.Seebeck_mu) @ self.Conductivity_mu
        self.Power_Factor_mu *= 1e-9  # milliWatt / m / K**2
Exemplo n.º 8
0
    # Save the result
    serialization.save_calculation(
        bt2file, data, equivalences, coeffs,
        serialization.gen_bt2_metadata(data, data.mommat is not None))

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

# 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([300.])
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
UCvol = data.get_volume()
sigma, seebeck, kappa, Hall = BL.calc_Onsager_coefficients(
    L0, L1, L2, mur, TEMP, UCvol)