Пример #1
0
    def physical_mode(self):
        """Calculate physical modes. Non physical modes are the first 3 modes of q=(0, 0, 0) and, if defined, all the
        modes outside the frequency range min_frequency and max_frequency.
        Returns
        -------
        physical_mode : np array
            (n_k_points, n_modes) bool
        """
        q_points = self._reciprocal_grid.unitary_grid(is_wrapping=False)
        physical_mode = np.zeros((self.n_k_points, self.n_modes),
                                 dtype=np.bool)

        for ik in range(len(q_points)):
            q_point = q_points[ik]
            phonon = HarmonicWithQ(
                q_point=q_point,
                second=self.forceconstants.second,
                distance_threshold=self.forceconstants.distance_threshold,
                folder=self.folder,
                storage=self.storage,
                is_nw=self.is_nw,
                is_unfolding=self.is_unfolding)

            physical_mode[ik] = phonon.physical_mode
        if self.min_frequency is not None:
            physical_mode[self.frequency < self.min_frequency] = False
        if self.max_frequency is not None:
            physical_mode[self.frequency > self.max_frequency] = False
        return physical_mode
Пример #2
0
    def _eigensystem(self):
        """Calculate the eigensystems, for each k point in k_points.

        Returns
        -------
        _eigensystem : np.array(n_k_points, n_unit_cell * 3, n_unit_cell * 3 + 1)
            eigensystem is calculated for each k point, the three dimensional array
            records the eigenvalues in the last column of the last dimension.

            If the system is not amorphous, these values are stored as complex numbers.
        """
        q_points = self._reciprocal_grid.unitary_grid(is_wrapping=False)
        shape = (self.n_k_points, self.n_modes + 1, self.n_modes)
        log_size(shape, name='eigensystem', type=np.complex)
        eigensystem = np.zeros(shape, dtype=np.complex)
        for ik in range(len(q_points)):
            q_point = q_points[ik]
            phonon = HarmonicWithQ(
                q_point=q_point,
                second=self.forceconstants.second,
                distance_threshold=self.forceconstants.distance_threshold,
                folder=self.folder,
                storage=self.storage,
                is_nw=self.is_nw,
                is_unfolding=self.is_unfolding)

            eigensystem[ik] = phonon._eigensystem

        return eigensystem
Пример #3
0
    def participation_ratio(self):
        """Calculates the participation ratio of each normal mode. Participation ratio's
        represent the fraction of atoms that are displaced meaning a value of 1 corresponds
        to translation. Defined by equations in DOI: 10.1103/PhysRevB.53.11469
        Returns
        -------
        participation_ratio : np array
            (n_k_points, n_modes) atomic participation
        """
        q_points = self._reciprocal_grid.unitary_grid(is_wrapping=False)
        participation_ratio = np.zeros((self.n_k_points, self.n_modes))
        for ik in range(len(q_points)):
            q_point = q_points[ik]
            phonon = HarmonicWithQ(
                q_point=q_point,
                second=self.forceconstants.second,
                distance_threshold=self.forceconstants.distance_threshold,
                folder=self.folder,
                storage=self.storage,
                is_nw=self.is_nw,
                is_unfolding=self.is_unfolding)

            participation_ratio[ik] = phonon.participation_ratio

        return participation_ratio
Пример #4
0
    def velocity(self):
        """Calculates the velocity using Hellmann-Feynman theorem.

        Returns
        -------
        velocity : np array
            (n_k_points, n_unit_cell * 3, 3) velocity in 100m/s or A/ps
        """

        q_points = self._reciprocal_grid.unitary_grid(is_wrapping=False)
        velocity = np.zeros((self.n_k_points, self.n_modes, 3))
        for ik in range(len(q_points)):
            q_point = q_points[ik]
            phonon = HarmonicWithQ(q_point=q_point,
                                   second=self.forceconstants.second,
                                   distance_threshold=self.forceconstants.distance_threshold,
                                   folder=self.folder,
                                   storage=self.storage,
                                   is_unfolding=self.is_unfolding)
            velocity[ik] = phonon.velocity
        return velocity
Пример #5
0
    def frequency(self):
        """Calculate phonons frequency
        Returns
        -------
        frequency : np array
            (n_k_points, n_modes) frequency in THz
        """
        q_points = self._reciprocal_grid.unitary_grid(is_wrapping=False)
        frequency = np.zeros((self.n_k_points, self.n_modes))
        for ik in range(len(q_points)):
            q_point = q_points[ik]
            phonon = HarmonicWithQ(q_point=q_point,
                                   second=self.forceconstants.second,
                                   distance_threshold=self.forceconstants.distance_threshold,
                                   folder=self.folder,
                                   storage=self.storage,
                                   is_unfolding=self.is_unfolding)

            frequency[ik] = phonon.frequency

        return frequency
Пример #6
0
    def participation_ratio(self):
        """Calculate phonons participation ratio. A value of 1 corresponds to translation.
        Returns
        -------
        participation_ratio : np array
            (n_k_points, n_modes) atomic participation
        """
        q_points = self._reciprocal_grid.unitary_grid(is_wrapping=False)
        participation_ratio = np.zeros((self.n_k_points, self.n_modes))
        for ik in range(len(q_points)):
            q_point = q_points[ik]
            phonon = HarmonicWithQ(
                q_point=q_point,
                second=self.forceconstants.second,
                distance_threshold=self.forceconstants.distance_threshold,
                folder=self.folder,
                storage=self.storage,
                is_nw=self.is_nw,
                is_unfolding=self.is_unfolding)

            participation_ratio[ik] = phonon.participation_ratio

        return participation_ratio
Пример #7
0
def plot_dispersion(phonons,
                    n_k_points=300,
                    is_showing=True,
                    symprec=1e-3,
                    is_nw=None,
                    with_velocity=True,
                    color='b',
                    is_unfolding=False):
    atoms = phonons.atoms
    if is_nw is None and phonons.is_nw:
        is_nw = phonons.is_nw
    if is_nw:
        q = np.linspace(0, 0.5, n_k_points)
        k_list = np.zeros((n_k_points, 3))
        k_list[:, 0] = q
        k_list[:, 2] = q
        Q = [0, 0.5]
        point_names = ['$\\Gamma$', 'X']
    else:
        try:
            k_list, Q, point_names = create_k_and_symmetry_space(
                atoms, n_k_points=n_k_points, symprec=symprec)
            q = np.linspace(0, 1, k_list.shape[0])
        except seekpath.hpkot.SymmetryDetectionError as err:
            print(err)
            q = np.linspace(0, 0.5, n_k_points)
            k_list = np.zeros((n_k_points, 3))
            k_list[:, 0] = q
            k_list[:, 2] = q
            Q = [0, 0.5]
            point_names = ['$\\Gamma$', 'X']
    freqs_plot = []
    vel_plot = []
    vel_norm = []
    for q_point in k_list:
        phonon = HarmonicWithQ(
            q_point,
            phonons.forceconstants.second,
            distance_threshold=phonons.forceconstants.distance_threshold,
            storage='memory',
            is_unfolding=is_unfolding)
        freqs_plot.append(phonon.frequency.flatten())
        if with_velocity:
            val_value = phonon.velocity[0]
            vel_plot.append(val_value)
            vel_norm.append(np.linalg.norm(val_value, axis=-1))
    freqs_plot = np.array(freqs_plot)
    if with_velocity:
        vel_plot = np.array(vel_plot)
        vel_norm = np.array(vel_norm)
    fig1, ax1 = plt.subplots()
    plt.tick_params(axis='both', which='minor', labelsize=16)
    plt.ylabel("$\\nu$ (THz)", fontsize=16)
    plt.xlabel('$q$', fontsize=16)
    plt.tick_params(axis='both', which='major', labelsize=16)
    plt.xticks(Q, point_names)
    plt.xlim(q[0], q[-1])
    if color is not None:
        plt.plot(q, freqs_plot, '.', color=color, linewidth=4, markersize=4)
    else:
        plt.plot(q, freqs_plot, '.', linewidth=4, markersize=4)
    plt.grid()
    plt.ylim(freqs_plot.min(), freqs_plot.max() * 1.05)
    folder = get_folder_from_label(phonons, base_folder=DEFAULT_FOLDER)
    if not os.path.exists(folder):
        os.makedirs(folder)
    plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)
    fig1.savefig(folder + '/' + 'dispersion' + '.png')
    np.savetxt(folder + '/' + 'q', q)
    np.savetxt(folder + '/' + 'dispersion', freqs_plot)
    if is_showing:
        plt.show()
    else:
        plt.close()
    if with_velocity:
        for alpha in range(3):
            np.savetxt(folder + '/' + 'velocity_' + str(alpha),
                       vel_plot[:, :, alpha])
        fig2, ax2 = plt.subplots()
        plt.ylabel('$|v|(\AA/ps)$', fontsize=16)
        plt.xlabel('$q$', fontsize=16)
        plt.tick_params(axis='both', which='major', labelsize=16)
        plt.tick_params(axis='both', which='minor', labelsize=20)
        plt.xticks(Q, point_names)
        plt.xlim(q[0], q[-1])
        if color is not None:
            plt.plot(q,
                     vel_norm[:, :],
                     '.',
                     linewidth=4,
                     markersize=4,
                     color=color)
        else:
            plt.plot(q, vel_norm[:, :], '.', linewidth=4, markersize=4)

        plt.grid()
        plt.tick_params(axis='both', which='major', labelsize=16)
        fig2.savefig(folder + '/' + 'velocity.png')
        np.savetxt(folder + '/' + 'velocity_norm', vel_norm)
        if is_showing:
            plt.show()
        else:
            plt.close()