Beispiel #1
0
 def _set_uniform_frequency_points(self, f_min, f_max):
     if self._frequency_points is None:
         self._frequency_points = get_frequency_points(
             f_min,
             f_max,
             frequency_step=self._frequency_step,
             num_frequency_points=self._num_frequency_points)
Beispiel #2
0
 def _set_frequency_points(self):
     if (self._interaction.get_phonons()[2] == 0).any():
         if self._log_level:
             print("Running harmonic phonon calculations...")
         self._interaction.run_phonon_solver()
     max_phonon_freq = np.amax(self._interaction.get_phonons()[0])
     self._frequency_points = get_frequency_points(
         max_phonon_freq=max_phonon_freq,
         sigmas=self._sigmas,
         frequency_points=self._frequency_points_in,
         frequency_step=self._frequency_step,
         num_frequency_points=self._num_frequency_points)
Beispiel #3
0
    def _run_c_with_g(self):
        self.run_phonon_solver(self._triplets_at_q.ravel())
        max_phonon_freq = np.max(self._frequencies)
        self._frequency_points = get_frequency_points(
            max_phonon_freq=max_phonon_freq,
            sigmas=[
                self._sigma,
            ],
            frequency_points=None,
            frequency_step=self._frequency_step,
            num_frequency_points=self._num_frequency_points)
        num_freq_points = len(self._frequency_points)
        num_mesh = np.prod(self._mesh)

        if self._temperatures is None:
            jdos = np.zeros((num_freq_points, 2), dtype='double')
        else:
            num_temps = len(self._temperatures)
            jdos = np.zeros((num_temps, num_freq_points, 2), dtype='double')
            occ_phonons = []
            for t in self._temperatures:
                freqs = self._frequencies[self._triplets_at_q[:, 1:]]
                occ_phonons.append(
                    np.where(freqs > self._cutoff_frequency,
                             bose_einstein(freqs, t), 0))

        for i, freq_point in enumerate(self._frequency_points):
            g, _ = get_triplets_integration_weights(
                self,
                np.array([freq_point], dtype='double'),
                self._sigma,
                is_collision_matrix=True,
                neighboring_phonons=(i == 0))

            if self._temperatures is None:
                jdos[i, 1] = np.sum(
                    np.tensordot(g[0, :, 0], self._weights_at_q, axes=(0, 0)))
                gx = g[2] - g[0]
                jdos[i, 0] = np.sum(
                    np.tensordot(gx[:, 0], self._weights_at_q, axes=(0, 0)))
            else:
                for j, n in enumerate(occ_phonons):
                    for k, l in list(np.ndindex(g.shape[3:])):
                        jdos[j, i, 1] += np.dot(
                            (n[:, 0, k] + n[:, 1, l] + 1) * g[0, :, 0, k, l],
                            self._weights_at_q)
                        jdos[j, i, 0] += np.dot(
                            (n[:, 0, k] - n[:, 1, l]) * g[1, :, 0, k, l],
                            self._weights_at_q)

        self._joint_dos = jdos / num_mesh
Beispiel #4
0
    def _set_frequency_points(self):
        if (self._pp.get_phonons()[2] == 0).any():
            if self._log_level:
                print("Running harmonic phonon calculations...")
            self._pp.run_phonon_solver()

        # Set phonon at Gamma without NAC for finding max_phonon_freq.
        self._pp.run_phonon_solver_at_gamma()
        max_phonon_freq = np.amax(self._pp.get_phonons()[0])
        self._pp.run_phonon_solver_at_gamma(is_nac=True)

        self._frequency_points = get_frequency_points(
            max_phonon_freq=max_phonon_freq,
            sigmas=self._sigmas,
            frequency_points=self._frequency_points_in,
            frequency_step=self._frequency_step,
            num_frequency_points=self._num_frequency_points,
        )
Beispiel #5
0
def get_real_self_energy(interaction,
                         grid_points,
                         temperatures,
                         run_on_bands=False,
                         frequency_points=None,
                         frequency_step=None,
                         num_frequency_points=None,
                         epsilons=None,
                         write_hdf5=True,
                         output_filename=None,
                         log_level=0):
    if epsilons is None:
        _epsilons = [
            None,
        ]
    else:
        _epsilons = epsilons

    _temperatures = np.array(temperatures, dtype='double')

    if (interaction.get_phonons()[2] == 0).any():
        if log_level:
            print("Running harmonic phonon calculations...")
        interaction.run_phonon_solver()

    fst = RealSelfEnergy(interaction)
    mesh = interaction.mesh_numbers
    frequencies = interaction.get_phonons()[0]
    max_phonon_freq = np.amax(frequencies)
    band_indices = interaction.band_indices

    if run_on_bands:
        _frequency_points = None
        all_deltas = np.zeros((len(_epsilons), len(grid_points),
                               len(_temperatures), len(band_indices)),
                              dtype='double',
                              order='C')
    else:
        _frequency_points = get_frequency_points(
            max_phonon_freq=max_phonon_freq,
            sigmas=epsilons,
            frequency_points=frequency_points,
            frequency_step=frequency_step,
            num_frequency_points=num_frequency_points)
        all_deltas = np.zeros(
            (len(_epsilons), len(grid_points), len(_temperatures),
             len(band_indices), len(_frequency_points)),
            dtype='double',
            order='C')
        fst.frequency_points = _frequency_points

    for j, gp in enumerate(grid_points):
        fst.grid_point = gp
        if log_level:
            weights = interaction.get_triplets_at_q()[1]
            print("------ Re self-energy -o- at grid point %d ------" % gp)
            print("Number of ir-triplets: %d / %d" %
                  (len(weights), weights.sum()))

        fst.run_interaction()
        frequencies = interaction.get_phonons()[0][gp]

        if log_level:
            qpoint = interaction.grid_address[gp] / mesh.astype(float)
            print("Phonon frequencies at (%4.2f, %4.2f, %4.2f):" %
                  tuple(qpoint))
            for bi, freq in enumerate(frequencies):
                print("%3d  %f" % (bi + 1, freq))

        for i, epsilon in enumerate(_epsilons):
            fst.epsilon = epsilon
            for k, t in enumerate(_temperatures):
                fst.temperature = t
                fst.run()
                all_deltas[i, j, k] = fst.real_self_energy.T

                # if not run_on_bands:
                #     pos = 0
                #     for bi_set in [[bi, ] for bi in band_indices]:
                #         filename = write_real_self_energy(
                #             gp,
                #             bi_set,
                #             _frequency_points,
                #             all_deltas[i, j, k, pos:(pos + len(bi_set))],
                #             mesh,
                #             fst.epsilon,
                #             t,
                #             filename=output_filename)
                #         pos += len(bi_set)

                #         if log_level:
                #             print("Real part of self energies were stored in "
                #                   "\"%s\"." % filename)
                #         sys.stdout.flush()

            if write_hdf5:
                filename = write_real_self_energy_to_hdf5(
                    gp,
                    band_indices,
                    _temperatures,
                    all_deltas[i, j],
                    mesh,
                    fst.epsilon,
                    frequency_points=_frequency_points,
                    frequencies=frequencies,
                    filename=output_filename)

                if log_level:
                    print("Real part of self energies were stored in \"%s\"." %
                          filename)
                    sys.stdout.flush()

    return _frequency_points, all_deltas
Beispiel #6
0
    def run(self, grid_points, write_jdos=False):
        """Calculate joint-density-of-states."""
        if self._log_level:
            print("--------------------------------- Joint DOS "
                  "---------------------------------")
            print("Running harmonic phonon calculations...", flush=True)

        self._jdos.run_phonon_solver()
        frequencies, _, _ = self._jdos.get_phonons()
        self._jdos.run_phonon_solver_at_gamma()
        max_phonon_freq = np.max(frequencies)
        self._jdos.run_phonon_solver_at_gamma(is_nac=True)

        self._frequency_points = get_frequency_points(
            max_phonon_freq=max_phonon_freq,
            sigmas=self._sigmas,
            frequency_points=None,
            frequency_step=self._frequency_step,
            num_frequency_points=self._num_frequency_points,
        )
        batches = get_freq_points_batches(
            len(self._frequency_points),
            nelems=self._num_frequency_points_in_batch)
        if self._temperatures is None:
            temperatures = [None]
        else:
            temperatures = self._temperatures
        self._joint_dos = np.zeros(
            (
                len(self._sigmas),
                len(temperatures),
                len(self._frequency_points),
                2,
            ),
            dtype="double",
            order="C",
        )

        for i, gp in enumerate(grid_points):
            if (self._bz_grid.addresses[gp] == 0).all():
                self._jdos.nac_q_direction = self._nac_q_direction
            else:
                self._jdos.nac_q_direction = None
            self._jdos.set_grid_point(gp)

            if self._log_level:
                weights = self._jdos.get_triplets_at_q()[1]
                print("======================= "
                      "Grid point %d (%d/%d) "
                      "=======================" %
                      (gp, i + 1, len(grid_points)))
                adrs = self._jdos.bz_grid.addresses[gp]
                q = np.dot(adrs, self._bz_grid.QDinv.T)
                print("q-point: (%5.2f %5.2f %5.2f)" % tuple(q))
                print("Number of triplets: %d" % len(weights))
                print("Frequency")
                for f in self._jdos.get_phonons()[0][gp]:
                    print("%8.3f" % f)

            if not self._sigmas:
                raise RuntimeError(
                    "sigma or tetrahedron method has to be set.")

            for i_s, sigma in enumerate(self._sigmas):
                self._jdos.sigma = sigma
                if self._log_level:
                    if sigma is None:
                        print("Tetrahedron method is used.")
                    else:
                        print("Smearing method with sigma=%s is used." % sigma)
                    print(
                        f"Calculations at {len(self._frequency_points)} "
                        f"frequency points are devided into {len(batches)} batches."
                    )
                for i_t, temperature in enumerate(temperatures):
                    self._jdos.temperature = temperature

                    for ib, freq_indices in enumerate(batches):
                        if self._log_level:
                            print(
                                f"{ib + 1}/{len(batches)}: {freq_indices + 1}",
                                flush=True,
                            )
                        self._jdos.frequency_points = self._frequency_points[
                            freq_indices]
                        self._jdos.run()
                        self._joint_dos[i_s, i_t,
                                        freq_indices] = self._jdos.joint_dos

                    if write_jdos:
                        filename = self._write(gp, i_sigma=i_s)
                        if self._log_level:
                            print('JDOS is written into "%s".' % filename)
Beispiel #7
0
def get_real_self_energy(
    interaction: Interaction,
    grid_points,
    temperatures,
    epsilons=None,
    frequency_points=None,
    frequency_step=None,
    num_frequency_points=None,
    frequency_points_at_bands=False,
    write_hdf5=True,
    output_filename=None,
    log_level=0,
):
    """Real part of self energy at frequency points.

    Band indices to be calculated at are kept in Interaction instance.

    Parameters
    ----------
    interaction : Interaction
        Ph-ph interaction.
    grid_points : array_like
        Grid-point indices where imag-self-energeis are caclculated.
        dtype=int, shape=(grid_points,)
    temperatures : array_like
        Temperatures where imag-self-energies are calculated.
        dtype=float, shape=(temperatures,)
    epsilons : array_like
        Smearing widths to computer principal part. When multiple values
        are given frequency shifts for those values are returned.
        dtype=float, shape=(epsilons,)
    frequency_points : array_like, optional
        Frequency sampling points. Default is None. With
        frequency_points_at_bands=False and frequency_points is None,
        num_frequency_points or frequency_step is used to generate uniform
        frequency sampling points.
        dtype=float, shape=(frequency_points,)
    frequency_step : float, optional
        Uniform pitch of frequency sampling points. Default is None. This
        results in using num_frequency_points.
    num_frequency_points: int, optional
        Number of sampling sampling points to be used instead of
        frequency_step. This number includes end points. Default is None,
        which gives 201.
    frequency_points_at_bands : bool, optional
        Phonon band frequencies are used as frequency points when True.
        Default is False.
    num_points_in_batch: int, optional
        Number of sampling points in one batch. This is for the frequency
        sampling mode and the sampling points are divided into batches.
        Lager number provides efficient use of multi-cores but more
        memory demanding. Default is None, which give the number of 10.
    log_level: int
        Log level. Default is 0.

    Returns
    -------
    tuple :
        (frequency_points, all_deltas) are returned.

        When frequency_points_at_bands is True,

            all_deltas.shape = (epsilons, temperatures, grid_points,
                                band_indices)

        otherwise

            all_deltas.shape = (epsilons, temperatures, grid_points,
                                band_indices, frequency_points)

    """
    if epsilons is None:
        _epsilons = [
            None,
        ]
    else:
        _epsilons = epsilons

    _temperatures = np.array(temperatures, dtype="double")

    if (interaction.get_phonons()[2] == 0).any():
        if log_level:
            print("Running harmonic phonon calculations...")
        interaction.run_phonon_solver()

    fst = RealSelfEnergy(interaction)
    mesh = interaction.mesh_numbers
    bz_grid = interaction.bz_grid

    # Set phonon at Gamma without NAC for finding max_phonon_freq.
    interaction.run_phonon_solver_at_gamma()
    max_phonon_freq = np.amax(interaction.get_phonons()[0])
    interaction.run_phonon_solver_at_gamma(is_nac=True)

    band_indices = interaction.band_indices

    if frequency_points_at_bands:
        _frequency_points = None
        all_deltas = np.zeros(
            (len(_epsilons), len(_temperatures), len(grid_points),
             len(band_indices)),
            dtype="double",
            order="C",
        )
    else:
        _frequency_points = get_frequency_points(
            max_phonon_freq=max_phonon_freq,
            sigmas=epsilons,
            frequency_points=frequency_points,
            frequency_step=frequency_step,
            num_frequency_points=num_frequency_points,
        )
        all_deltas = np.zeros(
            (
                len(_epsilons),
                len(_temperatures),
                len(grid_points),
                len(band_indices),
                len(_frequency_points),
            ),
            dtype="double",
            order="C",
        )
        fst.frequency_points = _frequency_points

    for j, gp in enumerate(grid_points):
        fst.grid_point = gp
        if log_level:
            weights = interaction.get_triplets_at_q()[1]
            if len(grid_points) > 1:
                print(
                    "------------------- Real part of self energy -o- (%d/%d) "
                    "-------------------" % (j + 1, len(grid_points)))
            else:
                print("----------------------- Real part of self energy -o- "
                      "-----------------------")
            print("Grid point: %d" % gp)
            print("Number of ir-triplets: %d / %d" %
                  (len(weights), weights.sum()))

        fst.run_interaction()
        frequencies = interaction.get_phonons()[0][gp]

        if log_level:
            bz_grid = interaction.bz_grid
            qpoint = np.dot(bz_grid.QDinv, bz_grid.addresses[gp])
            print("Phonon frequencies at (%4.2f, %4.2f, %4.2f):" %
                  tuple(qpoint))
            for bi, freq in enumerate(frequencies):
                print("%3d  %f" % (bi + 1, freq))
            sys.stdout.flush()

        for i, epsilon in enumerate(_epsilons):
            fst.epsilon = epsilon
            for k, t in enumerate(_temperatures):
                fst.temperature = t
                fst.run()
                all_deltas[i, k, j] = fst.real_self_energy.T

                # if not frequency_points_at_bands:
                #     pos = 0
                #     for bi_set in [[bi, ] for bi in band_indices]:
                #         filename = write_real_self_energy(
                #             gp,
                #             bi_set,
                #             _frequency_points,
                #             all_deltas[i, k, j, pos:(pos + len(bi_set))],
                #             mesh,
                #             fst.epsilon,
                #             t,
                #             filename=output_filename)
                #         pos += len(bi_set)

                #         if log_level:
                #             print("Real part of self energies were stored in "
                #                   "\"%s\"." % filename)
                #         sys.stdout.flush()

            if write_hdf5:
                filename = write_real_self_energy_to_hdf5(
                    gp,
                    band_indices,
                    _temperatures,
                    all_deltas[i, :, j],
                    mesh,
                    fst.epsilon,
                    bz_grid=bz_grid,
                    frequency_points=_frequency_points,
                    frequencies=frequencies,
                    filename=output_filename,
                )

                if log_level:
                    print('Real part of self energies were stored in "%s".' %
                          filename)
                    sys.stdout.flush()

    return _frequency_points, all_deltas