def get_thermodynamic_Gruneisen_parameter(gammas, frequencies, multiplicities, t): if t > 0: cv = mode_cv(t, frequencies * THzToEv) return (np.dot(multiplicities, cv * gammas).sum() / np.dot(multiplicities, cv).sum()) else: return 0.
def get_thermal_expansion_coefficient(gammas, frequencies, multiplicities, t): if t > 0: return np.dot(multiplicities, mode_cv(t, frequencies * THzToEv) * gammas).sum() else: return 0.
def get_thermodynamic_Gruneisen_parameter(gammas, frequencies, multiplicities, t): if t > 0: conditions = (frequencies > 0) freq_temp = np.where(conditions, x, 1) cv_temp = mode_cv(t, frequencies * THzToEv) cv = np.where(conditions, x, 0) return (np.dot(multiplicities, cv * gammas).sum() / np.dot(multiplicities, cv).sum()) else: return 0.
def mode_cv_matrix(temp, freqs, cutoff=1e-4): r"""Calculate mode heat capacity matrix, Cqjj'. C_{\mathbf{q}jj'} = K_B \frac{e^{x_{\mathbf{q}j} - x_{\mathbf{q}j'}} - 1} {x_{\mathbf{q}j} - x_{\mathbf{q}j'}} \left( \frac{ x_{\mathbf{q}j} + x_{\mathbf{q}j'}}{2} \right)^2 n_{\mathbf{q}j}(n_{\mathbf{q}j'} + 1) Note ---- Diagonal (j=j') terms reduce to normal mode heat capacity. Parameters ---------- temp : float Temperature in K. freqs : ndarray Phonon frequencies at a q-point in eV. cutoff : float This is used to check the degeneracy. Returns ------- ndarray Heat capacity matrix in eV/K. shape=(num_band, num_band), dtype='double', order='C'. """ x = freqs / Kb / temp shape = (len(freqs), len(freqs)) cvm = np.zeros(shape, dtype="double", order="C") for i, j in np.ndindex(shape): if abs(freqs[i] - freqs[j]) < cutoff: cvm[i, j] = mode_cv(temp, freqs[i]) continue sub = x[i] - x[j] add = x[i] + x[j] n_inv = np.exp([x[i], x[j], sub]) - 1 cvm[i, j] = Kb * n_inv[2] / sub * (add / 2) ** 2 / n_inv[0] * (1 / n_inv[1] + 1) return cvm
def get_thermodynamic_Gruneisen_parameter(gammas, frequencies, t): if t > 0: cv = mode_cv(t, frequencies * THzToEv) return np.sum(gammas * cv) / np.sum(cv) else: return 0.
def kappa_separate(self, gamma, thetaD, T, P=1, m=3, n=1): """ nkpts: number of phonon k-points frequencies: list of eigenvalue-arrays as output by phonopy vgroup: group velocities T: temperature in K following parameters from Eq (70) in Tritt book, p.14 P: proportionality factor of Umklapp scattering rate, defualt 1 mass: mass in amu (average mass of unitcell) gamma: Gruneisen parameter, unitless thetaD: Debye temperature of relevance (acoustic modes) 283K for Mo3Sb7 m = 3 by default n = 1 by default cellvol: unit cell volume in A^3 """ T = float(T) #self.phonon.set_mesh(mesh, is_eigenvectors=True) #self.mass = self.phonon.get_primitive().get_masses().sum()/self.phonon.get_primitive().get_number_of_atoms() self.cellvol = self.phonon.get_primitive().get_volume() self.qpoints, self.weigths, self.frequencies, self.eigvecs = self.phonon.get_mesh( ) nkpts = self.frequencies.shape[0] numbranches = self.frequencies.shape[1] self.group_velocity = np.zeros((nkpts, numbranches, 3)) for i in range(len(self.qpoints)): self.group_velocity[i, :, :] = self.phonon.get_group_velocity_at_q( self.qpoints[i]) inv_nor_Um = np.zeros((nkpts, numbranches)) inv_point_defect_mass_fc = np.zeros((nkpts, numbranches)) inv_tau_total = np.zeros((nkpts, numbranches)) kappa_Um = np.zeros((nkpts, numbranches)) kappa_point_defect_mass_fc = np.zeros((nkpts, numbranches)) kappa_total = np.zeros((nkpts, numbranches)) self.kappaten = np.zeros((nkpts, numbranches, 3, 3)) v_group = np.zeros((nkpts, numbranches)) capacity = np.zeros((nkpts, numbranches)) for i in range(nkpts): for j in range(numbranches): nu = self.frequencies[i][ j] # frequency (in Thz) of current mode velocity = self.group_velocity[ i, j, :] # cartesian vector of group velocity v_group = (velocity[0]**2 + velocity[1]**2 + velocity[2]**2)**(0.5) * THztoA capacity[i, j] = mode_cv( T, nu * THzToEv) * eV2Joule / (self.cellvol * Ang2meter**3) # tau inverse phonon-phonon, inverse lifetime inv_nor_Um[i, j] = P * hbar * gamma**2 / ( self.mass * amu) / v_group**2 * (T**n) / thetaD * ( 2 * np.pi * THz * nu)**2 * np.exp( (-1.0) * thetaD / m / T) # tau inverse point defect, inverse lifetime inv_point_defect_mass_fc[i, j] = (self.mass_fc_factor) * ( 2 * np.pi * THz * nu)**4 / v_group**3 # tau inverst, inverse lifetime inv_tau_total[ i, j] = inv_nor_Um[i, j] + inv_point_defect_mass_fc[i, j] kappa_total[ i, j] = (1.0 / 3.0) * self.weigths[i] * v_group**2 * capacity[ i, j] / inv_tau_total[i, j] # 1/3 is for isotropic condition kappa_Um[ i, j] = (1.0 / 3.0) * self.weigths[i] * v_group**2 * capacity[ i, j] / inv_nor_Um[i, j] # 1/3 is for isotropic condition kappa_point_defect_mass_fc[ i, j] = (1.0 / 3.0) * self.weigths[i] * v_group**2 * capacity[ i, j] / inv_point_defect_mass_fc[ i, j] # 1/3 is for isotropic condition self.kappaten[i, j, :, :] = self.weigths[i] * np.outer( velocity, velocity) * THztoA**2 * capacity[i, j] / inv_tau_total[i, j] #print(np.sum(inv_nor_Um, axis =1)) #print(np.sum(inv_point_defect_mass_fc, axis =1)) #print(np.sum(inv_tau_total, axis =1)) self.tau = np.concatenate( (inv_nor_Um, inv_point_defect_mass_fc, inv_tau_total), axis=1) self.kappa = [ kappa_Um.sum() / self.weigths.sum(), kappa_point_defect_mass_fc.sum() / self.weigths.sum(), kappa_total.sum() / self.weigths.sum() ] return self.tau, self.kappa, self.kappaten