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)
Exemple #2
0
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
Exemple #3
0
    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)
Exemple #4
0
 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
Exemple #5
0
    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())
Exemple #6
0
 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
Exemple #9
0
    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
Exemple #10
0
 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
Exemple #12
0
 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
Exemple #13
0
 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]
Exemple #14
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)