Пример #1
0
    def population(self):
        """Calculate the phonons population for each k point in k_points and each mode.
        If classical, it returns the temperature divided by each frequency, using equipartition theorem.
        If quantum it returns the Bose-Einstein distribution

        Returns
        -------
        population : np.array(n_k_points, n_modes)
            population for each k point and each mode
        """
        q_points = self._reciprocal_grid.unitary_grid(is_wrapping=False)
        population = np.zeros((self.n_k_points, self.n_modes))
        for ik in range(len(q_points)):
            q_point = q_points[ik]
            phonon = HarmonicWithQTemp(
                q_point=q_point,
                second=self.forceconstants.second,
                distance_threshold=self.forceconstants.distance_threshold,
                folder=self.folder,
                storage=self.storage,
                temperature=self.temperature,
                is_classic=self.is_classic,
                is_nw=self.is_nw,
                is_unfolding=self.is_unfolding)
            population[ik] = phonon.population
        return population
Пример #2
0
    def heat_capacity(self):
        """Calculate the heat capacity for each k point in k_points and each mode.
        If classical, it returns the Boltzmann constant in W/m/K. If quantum it returns the derivative of the
        Bose-Einstein weighted by each phonons energy.
        .. math::

            c_\\mu = k_B \\frac{\\nu_\\mu^2}{ \\tilde T^2} n_\\mu (n_\\mu + 1)

        where the frequency :math:`\\nu` and the temperature :math:`\\tilde T` are in THz.

        Returns
        -------
        c_v : np.array(n_k_points, n_modes)
            heat capacity in W/m/K for each k point and each mode
        """
        q_points = self._reciprocal_grid.unitary_grid(is_wrapping=False)
        c_v = np.zeros((self.n_k_points, self.n_modes))
        for ik in range(len(q_points)):
            q_point = q_points[ik]
            phonon = HarmonicWithQTemp(
                q_point=q_point,
                second=self.forceconstants.second,
                distance_threshold=self.forceconstants.distance_threshold,
                folder=self.folder,
                storage=self.storage,
                temperature=self.temperature,
                is_classic=self.is_classic,
                is_nw=self.is_nw,
                is_unfolding=self.is_unfolding)
            c_v[ik] = phonon.heat_capacity
        return c_v
Пример #3
0
    def heat_capacity_2d(self):
        """Calculate the generalized 2d heat capacity for each k point in k_points and each mode.
        If classical, it returns the Boltzmann constant in W/m/K.

        Returns
        -------
        heat_capacity_2d : np.array(n_k_points, n_modes, n_modes)
            heat capacity in W/m/K for each k point and each modes couple.
        """
        q_points = self._reciprocal_grid.unitary_grid(is_wrapping=False)
        shape = (self.n_k_points, self.n_modes, self.n_modes)
        log_size(shape, name='heat_capacity_2d', type=np.float)
        heat_capacity_2d = np.zeros(shape)
        for ik in range(len(q_points)):
            q_point = q_points[ik]
            phonon = HarmonicWithQTemp(
                q_point=q_point,
                second=self.forceconstants.second,
                distance_threshold=self.forceconstants.distance_threshold,
                folder=self.folder,
                storage=self.storage,
                temperature=self.temperature,
                is_classic=self.is_classic,
                is_nw=self.is_nw,
                is_unfolding=self.is_unfolding)
            heat_capacity_2d[ik] = phonon.heat_capacity_2d
        return heat_capacity_2d
Пример #4
0
    def calculate_conductivity_qhgk(self):
        """Calculates the conductivity of each mode using the :ref:'Quasi-Harmonic-Green-Kubo Model'.
        The tensor is returned individual modes along the first axis and has units of W/m/K.

        Returns
        -------
        conductivity_per_mode : np.array
            (n_phonons, 3, 3) W/m/K
        """
        phonons = self.phonons
        omega = phonons.omega.reshape((phonons.n_k_points, phonons.n_modes))
        volume = np.linalg.det(phonons.atoms.cell)
        q_points = phonons._reciprocal_grid.unitary_grid(is_wrapping=False)
        physical_mode = phonons.physical_mode
        conductivity_per_mode = np.zeros(
            (self.phonons.n_k_points, self.phonons.n_modes, 3, 3))
        diffusivity_with_axis = np.zeros_like(conductivity_per_mode)
        if self.diffusivity_shape == 'lorentz':
            logging.info('Using Lorentzian diffusivity_shape')
            curve = lorentz_delta
        elif self.diffusivity_shape == 'gauss':
            logging.info('Using Gaussian diffusivity_shape')
            curve = gaussian_delta
        elif self.diffusivity_shape == 'triangle':
            logging.info('Using triangular diffusivity_shape')
            curve = triangular_delta
        else:
            logging.error('Diffusivity shape not implemented')

        is_diffusivity_including_antiresonant = self.is_diffusivity_including_antiresonant

        if self.diffusivity_bandwidth is not None:
            logging.info('Using diffusivity bandwidth from input')
            diffusivity_bandwidth = self.diffusivity_bandwidth * np.ones(
                (phonons.n_k_points, phonons.n_modes))
        else:
            diffusivity_bandwidth = self.phonons.bandwidth.reshape(
                (phonons.n_k_points, phonons.n_modes)).copy() / 2.

        # if self.diffusivity_threshold is None:
        logging.info('Start calculation diffusivity')

        for k_index in range(len(q_points)):

            phonon = HarmonicWithQTemp(
                q_point=q_points[k_index],
                second=self.phonons.forceconstants.second,
                distance_threshold=self.phonons.forceconstants.
                distance_threshold,
                folder=self.folder,
                storage=self.storage,
                temperature=self.temperature,
                is_classic=self.is_classic,
                is_unfolding=self.is_unfolding)
            heat_capacity_2d = phonon.heat_capacity_2d
            if phonons.n_modes > 100:
                logging.info('calculating conductivity for q = ' +
                             str(q_points[k_index]))
            for alpha in range(3):
                if alpha == 0:
                    sij_left = phonon._sij_x
                if alpha == 1:
                    sij_left = phonon._sij_y
                if alpha == 2:
                    sij_left = phonon._sij_z
                for beta in range(3):
                    if beta == 0:
                        sij_right = phonon._sij_x
                    if beta == 1:
                        sij_right = phonon._sij_y
                    if beta == 2:
                        sij_right = phonon._sij_z
                    diffusivity = calculate_diffusivity(
                        omega[k_index], sij_left, sij_right,
                        diffusivity_bandwidth[k_index], physical_mode[k_index],
                        curve, is_diffusivity_including_antiresonant,
                        self.diffusivity_threshold)
                    conductivity_per_mode[k_index, :, alpha, beta] = (np.sum(heat_capacity_2d *
                                                                            diffusivity, axis=-1) \
                                                                     / (volume * phonons.n_k_points)).real
                    diffusivity_with_axis[k_index, :,
                                          alpha, beta] = np.sum(diffusivity,
                                                                axis=-1).real
        self._diffusivity = 1 / 3 * 1 / 100 * contract('knaa->kn',
                                                       diffusivity_with_axis)
        return conductivity_per_mode * 1e22