def _symmetrize_reducible_collision_matrix(self): import anharmonic._phono3py as phono3c phono3c.symmetrize_collision_matrix(self._collision_matrix) # Average matrix elements belonging to degenerate bands col_mat = self._collision_matrix for i, gp in enumerate(self._ir_grid_points): freqs = self._frequencies[gp] deg_sets = degenerate_sets(freqs) for dset in deg_sets: bi_set = [] for j in range(len(freqs)): if j in dset: bi_set.append(j) sum_col = (col_mat[:, :, i, bi_set, :, :].sum(axis=2) / len(bi_set)) for j in bi_set: col_mat[:, :, i, j, :, :] = sum_col for i, gp in enumerate(self._ir_grid_points): freqs = self._frequencies[gp] deg_sets = degenerate_sets(freqs) for dset in deg_sets: bi_set = [] for j in range(len(freqs)): if j in dset: bi_set.append(j) sum_col = (col_mat[:, :, :, :, i, bi_set].sum(axis=4) / len(bi_set)) for j in bi_set: col_mat[:, :, :, :, i, j] = sum_col
def _symmetrize_reducible_collision_matrix(self): import anharmonic._phono3py as phono3c phono3c.symmetrize_collision_matrix(self._collision_matrix) # Average matrix elements belonging to degenerate bands col_mat = self._collision_matrix for i, gp in enumerate(self._ir_grid_points): freqs = self._frequencies[gp] deg_sets = degenerate_sets(freqs) for dset in deg_sets: bi_set = [] for j in range(len(freqs)): if j in dset: bi_set.append(j) sum_col = (col_mat[:, :, i, bi_set, :, :].sum(axis=2) / len(bi_set)) for j in bi_set: col_mat[:, :, i, j, :, :] = sum_col for i, gp in enumerate(self._ir_grid_points): freqs = self._frequencies[gp] deg_sets = degenerate_sets(freqs) for dset in deg_sets: bi_set = [] for j in range(len(freqs)): if j in dset: bi_set.append(j) sum_col = (col_mat[:, :, :, :, i, bi_set].sum(axis=4) / len(bi_set)) for j in bi_set: col_mat[:, :, :, :, i, j] = sum_col
def _calculate_group_velocity_at_q(self, q): self._dynmat.set_dynamical_matrix(q) dm = self._dynmat.get_dynamical_matrix() eigvals, eigvecs = np.linalg.eigh(dm) eigvals = eigvals.real freqs = np.sqrt(abs(eigvals)) * np.sign(eigvals) * self._factor gv = np.zeros((len(freqs), 3), dtype='double', order='C') deg_sets = degenerate_sets(freqs) ddms = self._get_dD(np.array(q)) pos = 0 for deg in deg_sets: gv[pos:pos + len(deg)] = self._perturb_D(ddms, eigvecs[:, deg]) pos += len(deg) for i, f in enumerate(freqs): if f > self._cutoff_frequency: gv[i, :] *= self._factor**2 / f / 2 else: gv[i, :] = 0 if self._perturbation is None: if self._symmetry is None: return gv else: return self._symmetrize_group_velocity(gv, q) else: return gv
def _set_group_velocity_at_q(self, q): self._dynmat.set_dynamical_matrix(q) dm = self._dynmat.get_dynamical_matrix() eigvals, eigvecs = np.linalg.eigh(dm) eigvals = eigvals.real freqs = np.sqrt(abs(eigvals)) * np.sign(eigvals) * self._factor gv = np.zeros((len(freqs), 3), dtype='double') deg_sets = degenerate_sets(freqs) ddms = self._get_dD(np.array(q)) pos = 0 for deg in deg_sets: gv[pos:pos+len(deg)] = self._perturb_D(ddms, eigvecs[:, deg]) pos += len(deg) for i, f in enumerate(freqs): if f > self._cutoff_frequency: gv[i, :] *= self._factor ** 2 / f / 2 else: gv[i, :] = 0 if self._perturbation is None: return self._symmetrize_group_velocity(gv, q) else: return gv
def _calculate_group_velocity_matrix_at_q(self, q): self._dynmat.run(q) dm = self._dynmat.dynamical_matrix eigvals, eigvecs = np.linalg.eigh(dm) eigvals = eigvals.real freqs = np.sqrt(abs(eigvals)) * np.sign(eigvals) * self._factor deg_sets = degenerate_sets(freqs) ddms = self._get_dD(np.array(q)) rot_eigvecs = np.zeros_like(eigvecs) for deg in deg_sets: rot_eigvecs[:, deg] = self._rot_eigsets(ddms, eigvecs[:, deg]) condition = freqs > self._cutoff_frequency freqs = np.where(condition, freqs, 1) rot_eigvecs = rot_eigvecs * np.where(condition, 1 / np.sqrt(2 * freqs), 0) gvm = np.zeros((3, ) + eigvecs.shape, dtype=self._complex_dtype) for i, ddm in enumerate(ddms[1:]): ddm = ddm * (self._factor**2) gvm[i] = np.dot(rot_eigvecs.T.conj(), np.dot(ddm, rot_eigvecs)) if self._perturbation is None: if self._symmetry is None: return gvm else: return self._symmetrize_group_velocity_matrix(gvm, q) else: return gvm
def get_degenerated_frequencies(frequencies, normalized_frequencies): num_phonons = frequencies.shape[1] normalized_frequencies_degenerated = np.zeros_like(normalized_frequencies) for i, q_frequencies in enumerate(frequencies): degenerate_index = degenerate_sets(q_frequencies) weight_matrix = get_weights_from_index_list(num_phonons, degenerate_index) for j, weight in enumerate(weight_matrix): normalized_frequencies_degenerated[i, j]= np.average(normalized_frequencies[i, :], weights=weight) return normalized_frequencies_degenerated
def average_by_degeneracy(imag_self_energy, band_indices, freqs_at_gp): deg_sets = degenerate_sets(freqs_at_gp) imag_se = np.zeros_like(imag_self_energy) for dset in deg_sets: bi_set = [] for i, bi in enumerate(band_indices): if bi in dset: bi_set.append(i) for i in bi_set: if imag_self_energy.ndim == 1: imag_se[i] = (imag_self_energy[bi_set].sum() / len(bi_set)) else: imag_se[:, i] = (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: shifts[i] = (self._frequency_shifts[bi_set].sum() / len(bi_set)) return shifts
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: shifts[i] = (self._frequency_shifts[bi_set].sum() / len(bi_set)) return shifts
def _get_imag_self_energy(self, imag_self_energy): if self._cutoff_frequency is None: return imag_self_energy # Averaging imag-self-energies by degenerate bands imag_se = np.zeros_like(imag_self_energy) freqs = self._frequencies[self._grid_point] deg_sets = degenerate_sets(freqs) for dset in deg_sets: bi_set = [] for i, bi in enumerate(self._band_indices): if bi in dset: bi_set.append(i) for i in bi_set: if self._frequency_points is None: imag_se[i] = (imag_self_energy[bi_set].sum() / len(bi_set)) else: imag_se[:, i] = (imag_self_energy[:, bi_set].sum(axis=1) / len(bi_set)) return imag_se
def get_imag_self_energy(self): if self._cutoff_frequency is None: return self._imag_self_energy # 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) for dset in deg_sets: bi_set = [] for i, bi in enumerate(self._band_indices): if bi in dset: bi_set.append(i) for i in bi_set: if self._frequency_points 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_gv_operator(self, i_irgp, i_data): """Set velocity operator.""" irgp = self._grid_points[i_irgp] self._velocity_obj.run([self._get_qpoint_from_gp_index(irgp)]) gv_operator = self._velocity_obj.velocity_operators[0, :, :, :] self._gv_operator[i_data] = gv_operator[self._pp.band_indices, :, :] # gv = np.einsum("iij->ij", gv_operator).real deg_sets = degenerate_sets(self._frequencies[irgp]) # group velocities in the degenerate subspace are obtained diagonalizing the # velocity operator in the subspace of degeneracy. for id_dir in range(3): pos = 0 for deg in deg_sets: if len(deg) > 1: matrix_deg = gv_operator[ pos : pos + len(deg), pos : pos + len(deg), id_dir ] eigvals_deg = np.linalg.eigvalsh(matrix_deg) gv[pos : pos + len(deg), id_dir] = eigvals_deg pos += len(deg) # self._gv[i_data] = gv[self._pp.band_indices, :]
def real_self_energy(self): """Return calculated real-part of self-energies.""" if self._cutoff_frequency is None: return self._real_self_energies else: # Averaging frequency shifts by degenerate bands shifts = np.zeros_like(self._real_self_energies) freqs = self._frequencies[self._grid_point] deg_sets = degenerate_sets(freqs) # 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._frequency_points is None: shifts[i] = self._real_self_energies[bi_set].sum( ) / len(bi_set) else: shifts[:, i] = self._real_self_energies[:, bi_set].sum( axis=1) / len(bi_set) return shifts