def get_gv_by_sr0_at_stars(self, s,i,t): deg_sets = degenerate_sets(self._frequencies[i]) grid_point = self._grid_points[i] orig_address = self._grid_address[grid_point] rotations=get_rotations_for_star(orig_address, self._mesh, self._kpoint_operations) # self._get_group_veclocities_at_star(i, gv) gv_by_F_tensor = [] rec_lat = np.linalg.inv(self._primitive.get_cell()) rotations_cartesian = [similarity_transformation(rec_lat, r) for r in rotations] for rot_c in rotations_cartesian: gvs_rot = np.dot(rot_c, self._gv[i].T).T F_rot = np.dot(rot_c, self._F0[s,i,t].T).T # Take average of group veclocities of degenerate phonon modes # and then calculate gv x gv to preserve symmetry gvs = np.zeros_like(gvs_rot) Fs = np.zeros_like(F_rot) for deg in deg_sets: gv_ave = gvs_rot[deg].sum(axis=0) / len(deg) F_ave = F_rot[deg].sum(axis=0)/len(deg) for j in deg: gvs[j] = gv_ave Fs[j]=F_ave gv_by_F_tensor.append([np.outer(gvs[b], Fs[b]) for b in range(len(gvs))]) return np.array(gv_by_F_tensor)
def degenerate_at_grid(frequency_at_q): degeneracy = np.zeros_like(frequency_at_q, dtype="intc") deg_sets = degenerate_sets(frequency_at_q) for ele in deg_sets: for sub_ele in ele: degeneracy[sub_ele]=ele[0] return degeneracy
def get_gv_by_sr0_at_stars(self, s, i, t): deg_sets = degenerate_sets(self._frequencies[i]) grid_point = self._grid_points[i] orig_address = self._grid_address[grid_point] rotations = get_rotations_for_star(orig_address, self._mesh, self._kpoint_operations) # self._get_group_veclocities_at_star(i, gv) gv_by_F_tensor = [] rec_lat = np.linalg.inv(self._primitive.get_cell()) rotations_cartesian = [ similarity_transformation(rec_lat, r) for r in rotations ] for rot_c in rotations_cartesian: gvs_rot = np.dot(rot_c, self._gv[i].T).T F_rot = np.dot(rot_c, self._F0[s, i, t].T).T # Take average of group veclocities of degenerate phonon modes # and then calculate gv x gv to preserve symmetry gvs = np.zeros_like(gvs_rot) Fs = np.zeros_like(F_rot) for deg in deg_sets: gv_ave = gvs_rot[deg].sum(axis=0) / len(deg) F_ave = F_rot[deg].sum(axis=0) / len(deg) for j in deg: gvs[j] = gv_ave Fs[j] = F_ave gv_by_F_tensor.append( [np.outer(gvs[b], Fs[b]) for b in range(len(gvs))]) return np.array(gv_by_F_tensor)
def _get_degenerate_gv(self, i): deg_sets = degenerate_sets(self._frequencies[i]) gv = self._gv[i] gvs = np.zeros_like(gv) for deg in deg_sets: gv_ave = gv[deg].sum(axis=0) / len(deg) for j in deg: gvs[j] = gv_ave return gvs
def calculate_kappa(self): self._kappa = np.zeros(self._gamma.shape + (6,)) #resetting self._kappa assert len(np.unique(self._mapping))==len(self._frequency) # irreducible qpoint number if self._is_cahill_pohl: # tau = pi/omega --> 1/(2*2*pi*gamma) = 1/(2*f) --> gamma = f/(2*pi) for i, t in enumerate(self._ts): # pos = np.where(2 * np.pi * self._gamma[:,i] < self._frequency) # self._gamma[:,i][pos] = self._frequency[pos] / (2 * np.pi) self._gamma[:,i] = self._frequency / (2 * np.pi) if self._iso_gamma is not None: self._gamma+=self._iso_gamma try: import _kthin as kthin num_irr = self._frequency.shape[0] num_band = self._frequency.shape[1] degeneracy = np.zeros((num_irr, num_band), dtype="intc") for i in range(num_irr): deg = degenerate_sets(self._frequency[i]) for ele in deg: for sub_ele in ele: degeneracy[i, sub_ele]=ele[0] kthin.thermal_conductivity(self._kappa, self._rot_mappings.copy().astype("intc"), self._mapping.copy(), np.linalg.inv(self._cell.get_cell()).copy(), self._heat_capacity.copy(), self._gamma.copy(), self._gv.copy(), degeneracy.copy(), self._cutoff_lifetime) except ImportError: self.get_rotations_for_stars() for i, grid_point in enumerate(np.unique(self._map_to_ir_index)): gv2_tensors=self.get_gv_by_gv(i) self._gv2_tensors.append(gv2_tensors) # Sum all vxv at k* gv_sum2 =self.get_gv_sum(gv2_tensors) for k, l in list(np.ndindex(len(self._ts), self._natom*3)): if self._gamma[i, k, l] < 0.5 / self._cutoff_lifetime / THz: continue self._kappa[i, k, l, :] = ( gv_sum2[:, l] * self._heat_capacity[i,k, l] / self._gamma[i, k, l]) self._kappa *= self._conversion_factor / (2 * self._weight.sum())
def get_gv_by_gv(self,i): deg_sets = degenerate_sets(self._frequency[i]) orbits, rotations = self._reverse_mapping[i], self._kpt_rotations_at_stars[i] # self._get_group_veclocities_at_star(i, gv) gv2_tensor = [] rec_lat = np.linalg.inv(self._cell.get_cell()) rotations_cartesian = [similarity_transformation(rec_lat, r) for r in rotations] for rot_c in rotations_cartesian: gvs_rot = np.dot(rot_c, self._gv[i].T).T # Take average of group veclocities of degenerate phonon modes # and then calculate gv x gv to preserve symmetry gvs = np.zeros_like(gvs_rot) for deg in deg_sets: gv_ave = gvs_rot[deg].sum(axis=0) / len(deg) for j in deg: gvs[j] = gv_ave gv2_tensor.append([np.outer(gv, gv) for gv in gvs]) return np.array(gv2_tensor)
def get_imag_self_energy(self): if self._cutoff_frequency is None: return self._imag_self_energy else: # Averaging imag-self-energies by degenerate bands imag_se = np.zeros_like(self._imag_self_energy) freqs = self._frequencies[self._grid_point] deg_sets = degenerate_sets(freqs) # such like [[0,1], [2], [3,4,5]] for dset in deg_sets: bi_set = [] for i, bi in enumerate(self._band_indices): if bi in dset: bi_set.append(i) if len(bi_set) > 0: for i in bi_set: if self._fpoints is None: imag_se[i] = (self._imag_self_energy[bi_set].sum() / len(bi_set)) else: imag_se[:, i] = ( self._imag_self_energy[:, bi_set].sum(axis=1) / len(bi_set)) return imag_se
def get_frequency_shift(self): if self._cutoff_frequency is None: return self._frequency_shifts else: # Averaging frequency shifts by degenerate bands shifts = np.zeros_like(self._frequency_shifts) freqs = self._frequencies[self._grid_point] deg_sets = degenerate_sets(freqs) # such like [[0,1], [2], [3,4,5]] for dset in deg_sets: bi_set = [] for i, bi in enumerate(self._band_indices): if bi in dset: bi_set.append(i) if len(bi_set) > 0: for i in bi_set: if self._fpoints is None: shifts[i] = (self._frequency_shifts[bi_set].sum() / len(bi_set)) else: shifts[:, i] = ( self._frequency_shifts[:, bi_set].sum(axis=1) / len(bi_set)) return shifts
def _get_eigenvectors(self, q): if self._nac_q_direction is not None and (np.abs(q) < 1e-5).all(): self._dm.set_dynamical_matrix(q, q_direction=self._nac_q_direction) else: self._dm.set_dynamical_matrix(q) eigvals, eigvecs = np.linalg.eigh(self._dm.get_dynamical_matrix()) eigvals = eigvals.real if self._delta_q is None: return eigvals, eigvecs eigvecs_new = np.zeros_like(eigvecs) deg_sets = degenerate_sets(eigvals) if self._derivative_order is None: self._ddm.set_derivative_order(1) dD1 = self._get_dD(q) self._ddm.set_derivative_order(2) dD2 = self._get_dD(q) else: self._ddm.set_derivative_order(self._derivative_order) dD = self._get_dD(q) for deg in deg_sets: if len(deg) == 1: continue if self._derivative_order is not None: eigvecs_new = self._rearrange_eigenvectors(dD, eigvecs[:, deg]) else: eigvecs_new = self._rearrange_eigenvectors(dD1, eigvecs[:, deg]) if eigvecs_new is None: eigvecs_new = self._rearrange_eigenvectors( dD2, eigvecs[:, deg]) if eigvecs_new is not None: eigvecs[:, deg] = eigvecs_new return eigvals, eigvecs
def get_gv_nosym(self): if self._kpt_rotations_at_stars == None: self.get_rotations_for_stars() num_band = self._frequency.shape[1] gv_nosym = np.zeros((self._weight.sum(), num_band,3), dtype="double") for i, freq in enumerate(self._frequency): deg_sets = degenerate_sets(freq) orbits, rotations = self._reverse_mapping[i], self._kpt_rotations_at_stars[i] gv_at_orbits = np.zeros((len(orbits), num_band, 3), dtype="double") rec_lat = np.linalg.inv(self._cell.get_cell()) rotations_cartesian = [similarity_transformation(rec_lat, r) for r in rotations] for j, rot_c in enumerate(rotations_cartesian): gvs_rot = np.dot(rot_c, self._gv[i].T).T # Take average of group veclocities of degenerate phonon modes # and then calculate gv x gv to preserve symmetry gvs = np.zeros_like(gvs_rot) for deg in deg_sets: gv_ave = gvs_rot[deg].sum(axis=0) / len(deg) for k in deg: gv_at_orbits[j,k] = gv_ave gv_nosym[orbits] = gv_at_orbits return gv_nosym
def get_frequency_shift(self): if self._cutoff_frequency is None: return self._frequency_shifts else: # Averaging frequency shifts by degenerate bands shifts = np.zeros_like(self._frequency_shifts) freqs = self._frequencies[self._grid_point] deg_sets = degenerate_sets( freqs) # such like [[0,1], [2], [3,4,5]] for dset in deg_sets: bi_set = [] for i, bi in enumerate(self._band_indices): if bi in dset: bi_set.append(i) if len(bi_set) > 0: for i in bi_set: if self._fpoints is None: shifts[i] = (self._frequency_shifts[bi_set].sum() / len(bi_set)) else: shifts[:, i] = ( self._frequency_shifts[:, bi_set].sum(axis=1) / len(bi_set)) return shifts
def get_imag_self_energy(self): if self._cutoff_frequency is None: return self._imag_self_energy else: # Averaging imag-self-energies by degenerate bands imag_se = np.zeros_like(self._imag_self_energy) freqs = self._frequencies[self._grid_point] deg_sets = degenerate_sets( freqs) # such like [[0,1], [2], [3,4,5]] for dset in deg_sets: bi_set = [] for i, bi in enumerate(self._band_indices): if bi in dset: bi_set.append(i) if len(bi_set) > 0: for i in bi_set: if self._fpoints is None: imag_se[i] = ( self._imag_self_energy[bi_set].sum() / len(bi_set)) else: imag_se[:, i] = ( self._imag_self_energy[:, bi_set].sum(axis=1) / len(bi_set)) return imag_se
def set_degenerate_at_grid(self, i): deg_sets = degenerate_sets(self._frequencies[i]) for ele in deg_sets: for sub_ele in ele: self._degeneracies[i, sub_ele]=ele[0]
def _set_kappa_at_sigmas(self, i): freqs = self._frequencies[i] # Group velocity [num_freqs, 3] if not self._read_gv: gv = get_group_velocity( self._qpoint, self._dm, self._symmetry, q_length=self._gv_delta_q, frequency_factor_to_THz=self._frequency_factor_to_THz) self._gv[i] = gv # self._gv[i] = self._get_degenerate_gv(i) # Heat capacity [num_temps, num_freqs] cv = self._get_cv(freqs) self._cv[i] = cv num_kstar_counted = False try: import anharmonic._phono3py as phono3c rec_lat = np.linalg.inv(self._primitive.get_cell()) kpt_rotations_at_q = self._get_rotations_for_star(i) if self._sigma_iteration_step == 0: self._sum_num_kstar += len(kpt_rotations_at_q) num_kstar_counted = True deg = degenerate_sets(self._frequencies[i]) degeneracy = np.zeros(len(self._frequencies[i]), dtype="intc") for ele in deg: for sub_ele in ele: degeneracy[sub_ele]=ele[0] for j, sigma in enumerate(self._sigmas): kappa_at_qs = np.zeros_like(self._kappa[j,i]) mfp = np.zeros((len(self._temperatures), self._frequencies.shape[1], 3), dtype="double") for t, temp in enumerate(self._temperatures): for k in range(3): mfp[t,:,k] = np.where(self._gamma[j,i,t] > 0.5 / self._cutoff_lifetime / THz, self._gv[i,:,k] / self._gamma[j,i,t], 0) phono3c.thermal_conductivity_at_grid(kappa_at_qs, kpt_rotations_at_q.astype("intc").copy(), rec_lat.copy(), cv.copy(), mfp.copy(), self._gv[i].copy(), degeneracy.copy()) self._kappa[j,i] = kappa_at_qs / 2 * self._conversion_factor except ImportError: print "Warning: kappa calculation (the final step) went wrong in the C implementation. Changing to python instead..." # Outer product of group velocities (v x v) [num_k*, num_freqs, 3, 3] gv_by_gv_tensor = self._get_gv_by_gv(i) if self._sigma_iteration_step == 0 and num_kstar_counted == False: self._sum_num_kstar += len(gv_by_gv_tensor) # Sum all vxv at k* gv_sum2 = np.zeros((6, len(freqs)), dtype='double') for j, vxv in enumerate( ([0, 0], [1, 1], [2, 2], [1, 2], [0, 2], [0, 1])): gv_sum2[j] = gv_by_gv_tensor[:, :, vxv[0], vxv[1]].sum(axis=0) # Kappa for j, sigma in enumerate(self._sigmas): for k, l in list(np.ndindex(len(self._temperatures), len(freqs))): if self._gamma[j, i, k, l] < 0.5 / self._cutoff_lifetime / THz: continue self._kappa[j, i, k, l, :] = ( gv_sum2[:, l] * cv[k, l] / (self._gamma[j, i, k, l] * 2) * self._conversion_factor)