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
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
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
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