Example #1
0
def _set_triplets_integration_weights_c(g, interaction, frequency_points):
    import anharmonic._phono3py as phono3c

    reciprocal_lattice = np.linalg.inv(interaction.get_primitive().get_cell())
    mesh = interaction.get_mesh_numbers()
    thm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
    grid_address = interaction.get_grid_address()
    bz_map = interaction.get_bz_map()
    triplets_at_q = interaction.get_triplets_at_q()[0]
    unique_vertices = thm.get_unique_tetrahedra_vertices()
    
    for i, j in zip((1, 2), (1, -1)):
        neighboring_grid_points = np.zeros(
            len(unique_vertices) * len(triplets_at_q), dtype='intc')
        phono3c.neighboring_grid_points(
            neighboring_grid_points,
            triplets_at_q[:, i].flatten(),
            j * unique_vertices,
            mesh,
            grid_address,
            bz_map)
        interaction.set_phonon(np.unique(neighboring_grid_points))

    phono3c.triplets_integration_weights(
        g,
        np.array(frequency_points, dtype='double'),
        thm.get_tetrahedra(),
        mesh,
        triplets_at_q,
        interaction.get_phonons()[0],
        grid_address,
        bz_map)
Example #2
0
def _set_triplets_integration_weights_c(g,
                                        interaction,
                                        frequency_points,
                                        neighboring_phonons=True):
    import anharmonic._phono3py as phono3c

    reciprocal_lattice = np.linalg.inv(interaction.get_primitive().get_cell())
    mesh = interaction.get_mesh_numbers()
    thm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
    grid_address = interaction.get_grid_address()
    bz_map = interaction.get_bz_map()
    triplets_at_q = interaction.get_triplets_at_q()[0]

    if neighboring_phonons:
        unique_vertices = thm.get_unique_tetrahedra_vertices()
        for i, j in zip((1, 2), (1, -1)):
            neighboring_grid_points = np.zeros(len(unique_vertices) *
                                               len(triplets_at_q),
                                               dtype='intc')
            phono3c.neighboring_grid_points(neighboring_grid_points,
                                            triplets_at_q[:, i].flatten(),
                                            j * unique_vertices, mesh,
                                            grid_address, bz_map)
            interaction.set_phonon(np.unique(neighboring_grid_points))

    phono3c.triplets_integration_weights(g, frequency_points,
                                         thm.get_tetrahedra(), mesh,
                                         triplets_at_q,
                                         interaction.get_phonons()[0],
                                         grid_address, bz_map)
Example #3
0
def _set_triplets_integration_weights_c(g,
                                        interaction,
                                        frequency_points=None,
                                        neighboring_phonons=True,
                                        triplets_at_q=None,
                                        band_indices=None,
                                        is_triplet_symmetry=False):
    import anharmonic._phono3py as phono3c
    if triplets_at_q == None:
        triplets_at_q = interaction.get_triplets_at_q()[0]
    if len(triplets_at_q) == 0:
        return
    reciprocal_lattice = np.linalg.inv(interaction.get_primitive().get_cell())
    mesh = interaction.get_mesh_numbers()
    thm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)

    grid_address = interaction.get_grid_address()
    bz_map = interaction.get_bz_map()
    if neighboring_phonons:
        unique_vertices = thm.get_unique_tetrahedra_vertices()
        for i in (1, 2, 0):  # index inside a triplet
            for j in (1, -1):
                neighboring_grid_points = np.zeros(
                    len(unique_vertices) * len(np.unique(triplets_at_q[:, i])),
                    dtype='intc')
                phono3c.neighboring_grid_points(
                    neighboring_grid_points,
                    np.unique(triplets_at_q[:, i]).astype("intc"),
                    j * unique_vertices, mesh, grid_address, bz_map)
            interaction.set_phonons(np.unique(neighboring_grid_points))

    frequencies = interaction.get_phonons()[0]

    if len(np.where(mesh == 1)[0]) < 2:
        if band_indices is None:
            phono3c.triplets_integration_weights_fpoints(
                g, frequency_points,
                thm.get_tetrahedra().astype("intc").copy(), mesh,
                triplets_at_q, frequencies, grid_address, bz_map)
        else:
            phono3c.triplets_integration_weights(
                g,
                thm.get_tetrahedra().astype("intc").copy(),
                mesh, triplets_at_q, frequencies,
                np.array(band_indices, dtype='intc'), grid_address, bz_map,
                is_triplet_symmetry)
    else:  # 1D case
        possible_shift = np.array((np.array(mesh) != 1), dtype='intc')
        relative_address = np.array(
            [[[0, 0, 0], possible_shift], [[0, 0, 0], -possible_shift]],
            dtype="intc")
        if band_indices is None:
            phono3c.triplets_integration_weights_1D_fpoints(
                g, frequency_points, relative_address, mesh, triplets_at_q,
                frequencies, grid_address, bz_map)
        else:
            phono3c.triplets_integration_weights_1D(
                g, relative_address, mesh, triplets_at_q, frequencies,
                np.array(band_indices, dtype='intc'), grid_address, bz_map,
                is_triplet_symmetry)
Example #4
0
    def run_at_frequencies(self,
                           value='I',
                           division_number=201,
                           frequency_points=None):
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency, max_frequency,
                                                 division_number)
        else:
            self._frequency_points = frequency_points

        num_ir_grid_points = len(self._ir_grid_points)
        num_band = self._cell.get_number_of_atoms() * 3
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros(
            (num_freqs, num_band, num_ir_grid_points), dtype='double')

        reciprocal_lattice = np.linalg.inv(self._cell.get_cell())
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()

        for i, gp in enumerate(self._ir_grid_points):
            self._set_tetrahedra_frequencies(gp)
            for ib, frequencies in enumerate(self._tetrahedra_frequencies):
                self._tm.set_tetrahedra_omegas(frequencies)
                self._tm.run(self._frequency_points, value=value)
                iw = self._tm.get_integration_weight()
                self._integration_weights[:, ib, i] = iw

        self._integration_weights /= np.prod(self._mesh)
Example #5
0
 def _run_tetrahedron_method_dos(self):
     mesh_numbers = self._mesh_object.mesh_numbers
     cell = self._mesh_object.dynamical_matrix.primitive
     reciprocal_lattice = np.linalg.inv(cell.get_cell())
     tm = TetrahedronMethod(reciprocal_lattice, mesh=mesh_numbers)
     self._dos = run_tetrahedron_method_dos(
         mesh_numbers, self._frequency_points, self._frequencies,
         self._mesh_object.grid_address,
         self._mesh_object.grid_mapping_table, tm.get_tetrahedra())
Example #6
0
File: dos.py Project: gcgs1/phonopy
 def _run_tetrahedron_method_dos(self):
     mesh = self._mesh_object.get_mesh_numbers()
     cell = self._mesh_object.get_dynamical_matrix().get_primitive()
     reciprocal_lattice = np.linalg.inv(cell.get_cell())
     tm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
     self._dos = run_tetrahedron_method_dos(
         mesh,
         self._frequency_points,
         self._frequencies,
         self._mesh_object.get_grid_address(),
         self._mesh_object.get_grid_mapping_table(),
         tm.get_tetrahedra())
Example #7
0
    def _set_gamma_at_sigmas_lowmem(self, i):
        band_indices = self._pp.get_band_indices()
        (svecs, multiplicity, p2s, s2p,
         masses) = self._pp.get_primitive_and_supercell_correspondence()
        fc3 = self._pp.get_fc3()
        triplets_at_q, weights_at_q, _, _ = self._pp.get_triplets_at_q()
        bz_map = self._pp.get_bz_map()
        symmetrize_fc3_q = 0
        reciprocal_lattice = np.linalg.inv(self._pp.get_primitive().get_cell())
        thm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)

        # It is assumed that self._sigmas = [None].
        for j, sigma in enumerate(self._sigmas):
            self._collision.set_sigma(sigma)
            if self._is_N_U:
                collisions = np.zeros(
                    (2, len(self._temperatures), len(band_indices)),
                    dtype='double',
                    order='C')
            else:
                collisions = np.zeros(
                    (len(self._temperatures), len(band_indices)),
                    dtype='double',
                    order='C')
            import phono3py._phono3py as phono3c
            phono3c.pp_collision(collisions, thm.get_tetrahedra(),
                                 self._frequencies, self._eigenvectors,
                                 triplets_at_q, weights_at_q,
                                 self._grid_address, bz_map, self._mesh, fc3,
                                 svecs, multiplicity, masses, p2s, s2p,
                                 band_indices, self._temperatures,
                                 self._is_N_U * 1, symmetrize_fc3_q,
                                 self._cutoff_frequency)
            col_unit_conv = self._collision.get_unit_conversion_factor()
            pp_unit_conv = self._pp.get_unit_conversion_factor()
            if self._is_N_U:
                col = collisions.sum(axis=0)
                col_N = collisions[0]
                col_U = collisions[1]
            else:
                col = collisions
            for k in range(len(self._temperatures)):
                self._gamma[j, k, i, :] = average_by_degeneracy(
                    col[k] * col_unit_conv * pp_unit_conv, band_indices,
                    self._frequencies[self._grid_points[i]])
                if self._is_N_U:
                    self._gamma_N[j, k, i, :] = average_by_degeneracy(
                        col_N[k] * col_unit_conv * pp_unit_conv, band_indices,
                        self._frequencies[self._grid_points[i]])
                    self._gamma_U[j, k, i, :] = average_by_degeneracy(
                        col_U[k] * col_unit_conv * pp_unit_conv, band_indices,
                        self._frequencies[self._grid_points[i]])
Example #8
0
 def _run_tetrahedron_method_dos(self):
     mesh_numbers = self._mesh_object.mesh_numbers
     cell = self._mesh_object.dynamical_matrix.primitive
     reciprocal_lattice = np.linalg.inv(cell.get_cell())
     tm = TetrahedronMethod(reciprocal_lattice, mesh=mesh_numbers)
     pdos = run_tetrahedron_method_dos(
         mesh_numbers,
         self._frequency_points,
         self._frequencies,
         self._mesh_object.grid_address,
         self._mesh_object.grid_mapping_table,
         tm.get_tetrahedra(),
         coef=self._eigvecs2)
     self._partial_dos = pdos.T
Example #9
0
 def _run_tetrahedron_method_dos(self):
     mesh = self._mesh_object.get_mesh_numbers()
     cell = self._mesh_object.get_dynamical_matrix().get_primitive()
     reciprocal_lattice = np.linalg.inv(cell.get_cell())
     tm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
     pdos = run_tetrahedron_method_dos(
         mesh,
         self._frequency_points,
         self._frequencies,
         self._mesh_object.get_grid_address(),
         self._mesh_object.get_grid_mapping_table(),
         tm.get_tetrahedra(),
         coef=self._eigvecs2)
     self._partial_dos = pdos.T
Example #10
0
    def run_at_frequencies(self,
                           value='I',
                           division_number=201,
                           frequency_points=None):                            
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency,
                                                 max_frequency,
                                                 division_number)
        else:
            self._frequency_points = frequency_points

        num_ir_grid_points = len(self._ir_grid_points)
        num_band = self._cell.get_number_of_atoms() * 3
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros(
            (num_freqs, num_band, num_ir_grid_points), dtype='double')

        reciprocal_lattice = np.linalg.inv(self._cell.get_cell())
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()

        for i, gp in enumerate(self._ir_grid_points):
            self._set_tetrahedra_frequencies(gp)
            for ib, frequencies in enumerate(self._tetrahedra_frequencies):
                self._tm.set_tetrahedra_omegas(frequencies)
                self._tm.run(self._frequency_points, value=value)
                iw = self._tm.get_integration_weight()
                self._integration_weights[:, ib, i] = iw

        self._integration_weights /= np.prod(self._mesh)
Example #11
0
 def _set_integration_weights(self):
     primitive_lattice = np.linalg.inv(self._primitive.get_cell())
     thm = TetrahedronMethod(primitive_lattice, mesh=self._mesh)
     num_grid_points = len(self._grid_points)
     num_band = self._primitive.get_number_of_atoms() * 3
     self._integration_weights = np.zeros(
         (num_grid_points, len(self._band_indices), num_band), dtype='double')
     self._set_integration_weights_c(thm)
Example #12
0
def get_unique_grid_points(grid_points, bz_grid):
    """Collect grid points on tetrahedron vertices around input grid points.

    Find grid points of 24 tetrahedra around each grid point and
    collect those grid points that are unique.

    Parameters
    ----------
    grid_points : array_like
        Grid point indices.
    bz_grid : BZGrid
        Grid information in reciprocal space.

    Returns
    -------
    ndarray
        Unique grid points on tetrahedron vertices around input grid points.
        shape=(unique_grid_points, ), dtype='int_'.

    """
    import phono3py._phono3py as phono3c

    if _check_ndarray_state(grid_points, "int_"):
        _grid_points = grid_points
    else:
        _grid_points = np.array(grid_points, dtype="int_")
    thm = TetrahedronMethod(bz_grid.microzone_lattice)
    unique_vertices = np.array(
        np.dot(thm.get_unique_tetrahedra_vertices(), bz_grid.P.T),
        dtype="int_",
        order="C",
    )
    neighboring_grid_points = np.zeros(
        len(unique_vertices) * len(_grid_points), dtype="int_"
    )
    phono3c.neighboring_grid_points(
        neighboring_grid_points,
        _grid_points,
        unique_vertices,
        bz_grid.D_diag,
        bz_grid.addresses,
        bz_grid.gp_map,
        bz_grid.store_dense_gp_map * 1 + 1,
    )
    unique_grid_points = np.array(np.unique(neighboring_grid_points), dtype="int_")
    return unique_grid_points
Example #13
0
    def set(self, value='I', division_number=201, frequency_points=None):
        self._grid_point_count = 0
        self._value = value
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency, max_frequency,
                                                 division_number)
        else:
            self._frequency_points = frequency_points

        num_ir_grid_points = len(self._ir_grid_points)
        num_band = self._cell.get_number_of_atoms() * 3
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros((num_freqs, num_band),
                                             dtype='double')
        reciprocal_lattice = np.linalg.inv(self._cell.get_cell())
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()
Example #14
0
 def _run_c(self, lang='Py'):
     if self._sigma is None:
         self._tetrahedron_method = TetrahedronMethod(
             self._reciprocal_lattice, mesh=self._mesh)
         if lang == 'C':
             self._run_c_tetrahedron_method()
         else:
             self._run_py_tetrahedron_method()
     else:
         self._run_smearing_method()
Example #15
0
def _set_triplets_integration_weights_c(g, g_zero, pp, frequency_points):
    import phono3py._phono3py as phono3c

    thm = TetrahedronMethod(pp.bz_grid.microzone_lattice)
    triplets_at_q = pp.get_triplets_at_q()[0]
    frequencies = pp.get_phonons()[0]
    phono3c.triplets_integration_weights(
        g,
        g_zero,
        frequency_points,  # f0
        np.array(np.dot(thm.get_tetrahedra(), pp.bz_grid.P.T), dtype="int_", order="C"),
        pp.bz_grid.D_diag,
        triplets_at_q,
        frequencies,  # f1
        frequencies,  # f2
        pp.bz_grid.addresses,
        pp.bz_grid.gp_map,
        pp.bz_grid.store_dense_gp_map * 1 + 1,
        g.shape[0],
    )
Example #16
0
def _set_triplets_integration_weights_c(g,
                                        g_zero,
                                        interaction,
                                        frequency_points,
                                        neighboring_phonons=False):
    import phono3py._phono3py as phono3c

    reciprocal_lattice = np.linalg.inv(interaction.get_primitive().get_cell())
    mesh = interaction.get_mesh_numbers()
    thm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
    grid_address = interaction.get_grid_address()
    bz_map = interaction.get_bz_map()
    triplets_at_q = interaction.get_triplets_at_q()[0]

    if neighboring_phonons:
        unique_vertices = thm.get_unique_tetrahedra_vertices()
        for i, j in zip((1, 2), (1, -1)):
            neighboring_grid_points = np.zeros(
                len(unique_vertices) * len(triplets_at_q), dtype=bz_map.dtype)
            phono3c.neighboring_grid_points(
                neighboring_grid_points,
                np.array(triplets_at_q[:, i], dtype='uintp').ravel(),
                j * unique_vertices,
                mesh,
                grid_address,
                bz_map)
            interaction.run_phonon_solver(np.unique(neighboring_grid_points))

    frequencies = interaction.get_phonons()[0]
    phono3c.triplets_integration_weights(
        g,
        g_zero,
        frequency_points,  # f0
        thm.get_tetrahedra(),
        mesh,
        triplets_at_q,
        frequencies,  # f1
        frequencies,  # f2
        grid_address,
        bz_map,
        g.shape[0])
Example #17
0
 def tetrahedra_specify(self, lang="C"):
     reciprocal_lattice = np.linalg.inv(self._primitive.get_cell())
     mesh = self._mesh
     if self._dim == 3:
         self._tetra = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
         relative_address = self._tetra.get_tetrahedra()
         if lang == "C":
             self._unique_vertices = self.get_unique_tetrahedra_C(
                 relative_address)
         else:
             self._unique_vertices = self.get_unique_tetrahedra_py(
                 relative_address)
     elif self._dim == 2:
         self._tri = TriagonalMethod(reciprocal_lattice, mesh=mesh)
         relative_address = self._tri.get_triagonal()
         if lang == "C":
             self._unique_vertices = self.get_unique_triagonal_C(
                 relative_address)
         else:
             self._unique_vertices = self.get_unique_triagonal_py(
                 relative_address)
Example #18
0
    def set(self, value="I", division_number=201, frequency_points=None):
        """Prepare environment to peform linear tetrahedron method."""
        self._grid_point_count = 0
        self._value = value
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency,
                                                 max_frequency,
                                                 division_number,
                                                 dtype="double")
        else:
            self._frequency_points = np.array(frequency_points, dtype="double")

        num_band = self._frequencies.shape[1]
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros((num_freqs, num_band),
                                             dtype="double")
        reciprocal_lattice = np.linalg.inv(self._cell.cell)
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()
Example #19
0
def test_SNF_tetrahedra_relative_grid(aln_lda):
    """Test relative grid addresses under GR-grid.

    Under GR-grid, grid point addressing becomes different from ordinal uniform
    grid. But P and Q matrices can be used to map betweewn these grid systems.
    In this test, the agreement is checked by representing them in Cartesian
    coordinates.

    """
    lat = aln_lda.primitive.cell
    mesh = 25

    for snf_coordinates, d_diag in zip(("direct", "reciprocal"),
                                       ([2, 8, 24], [1, 9, 45])):
        bzgrid = BZGrid(
            mesh,
            lattice=lat,
            symmetry_dataset=aln_lda.primitive_symmetry.dataset,
            use_grg=True,
            force_SNF=True,
            SNF_coordinates=snf_coordinates,
        )

        np.testing.assert_equal(bzgrid.D_diag, d_diag)

        plat = np.linalg.inv(aln_lda.primitive.cell)
        mlat = bzgrid.microzone_lattice
        thm = TetrahedronMethod(mlat)
        snf_tetrahedra = np.dot(thm.get_tetrahedra(), bzgrid.P.T)

        for mtet, ptet in zip(thm.get_tetrahedra(), snf_tetrahedra):
            np.testing.assert_allclose(
                np.dot(mtet, mlat.T),
                np.dot(np.dot(ptet, bzgrid.QDinv.T), plat.T),
                atol=1e-8,
            )
Example #20
0
    def _set_integration_weights_py(self):
        if self._bz_grid.store_dense_gp_map:
            raise NotImplementedError("Only for type-I bz_map.")
        if self._bz_grid.grid_matrix is not None:
            raise NotImplementedError(
                "Generalized regular grid is not supported.")
        thm = TetrahedronMethod(self._bz_grid.microzone_lattice)
        num_grid_points = len(self._grid_points)
        num_band = len(self._primitive) * 3
        self._integration_weights = np.zeros(
            (num_grid_points, len(self._band_indices), num_band),
            dtype="double")

        for i, gp in enumerate(self._grid_points):
            tfreqs = get_tetrahedra_frequencies(
                gp,
                self._bz_grid.D_diag,
                self._bz_grid.addresses,
                np.array(
                    np.dot(thm.get_tetrahedra(), self._bz_grid.P.T),
                    dtype="int_",
                    order="C",
                ),
                self._grid_points,
                self._frequencies,
                grid_order=[
                    1,
                    self._bz_grid.D_diag[0],
                    self._bz_grid.D_diag[0] * self._bz_grid.D_diag[1],
                ],
                lang="Py",
            )

            for bi, frequencies in enumerate(tfreqs):
                thm.set_tetrahedra_omegas(frequencies)
                thm.run(self._frequencies[self._grid_point,
                                          self._band_indices])
                iw = thm.get_integration_weight()
                self._integration_weights[i, :, bi] = iw
Example #21
0
    def set(self,
            value='I',
            division_number=201,
            frequency_points=None):
        self._grid_point_count = 0
        self._value = value
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency,
                                                 max_frequency,
                                                 division_number)
        else:
            self._frequency_points = frequency_points

        num_ir_grid_points = len(self._ir_grid_points)
        num_band = self._cell.get_number_of_atoms() * 3
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros((num_freqs, num_band),
                                             dtype='double')
        reciprocal_lattice = np.linalg.inv(self._cell.get_cell())
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()
Example #22
0
def _set_triplets_integration_weights_py(g, interaction, frequency_points):
    reciprocal_lattice = np.linalg.inv(interaction.get_primitive().get_cell())
    mesh = interaction.get_mesh_numbers()
    thm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
    grid_address = interaction.get_grid_address()
    bz_map = interaction.get_bz_map()
    triplets_at_q = interaction.get_triplets_at_q()[0]
    unique_vertices = thm.get_unique_tetrahedra_vertices()
    tetrahedra_vertices = get_tetrahedra_vertices(thm.get_tetrahedra(), mesh,
                                                  triplets_at_q, grid_address,
                                                  bz_map)
    interaction.set_phonon(np.unique(tetrahedra_vertices))
    frequencies = interaction.get_phonons()[0]
    num_band = frequencies.shape[1]
    for i, vertices in enumerate(tetrahedra_vertices):
        for j, k in list(np.ndindex((num_band, num_band))):
            f1_v = frequencies[vertices[0], j]
            f2_v = frequencies[vertices[1], k]
            thm.set_tetrahedra_omegas(f1_v + f2_v)
            thm.run(frequency_points)
            g0 = thm.get_integration_weight()
            g[0, i, :, j, k] = g0
            thm.set_tetrahedra_omegas(-f1_v + f2_v)
            thm.run(frequency_points)
            g1 = thm.get_integration_weight()
            thm.set_tetrahedra_omegas(f1_v - f2_v)
            thm.run(frequency_points)
            g2 = thm.get_integration_weight()
            g[1, i, :, j, k] = g1 - g2
            if len(g) == 3:
                g[2, i, :, j, k] = g0 + g1 + g2
Example #23
0
class TetrahedronMesh(object):
    def __init__(self,
                 cell,
                 frequencies, # only at ir-grid-points
                 mesh,
                 grid_address,
                 grid_mapping_table,
                 ir_grid_points,
                 grid_order=None,
                 lang='C'):
        self._cell = cell
        self._frequencies = frequencies
        self._mesh = np.array(mesh, dtype='intc')
        self._grid_address = grid_address
        self._grid_mapping_table = grid_mapping_table
        self._lang = lang
        if lang == 'C':
            self._grid_order = None
        else:
            if grid_order is None:
                self._grid_order = [1, mesh[0], mesh[0] * mesh[1]]
            else:
                self._grid_order = grid_order
        self._ir_grid_points = ir_grid_points

        self._gp_ir_index = None

        self._tm = None
        self._tetrahedra_frequencies = None
        self._integration_weights = None
        self._relative_grid_address = None

        self._frequency_points = None
        self._value = None

        self._grid_point_count = 0

        self._prepare()
        
    def __iter__(self):
        return self
            
    def __next__(self):
        if self._grid_point_count == len(self._ir_grid_points):
            raise StopIteration
        else:
            gp = self._ir_grid_points[self._grid_point_count]
            self._set_tetrahedra_frequencies(gp)
            for ib, frequencies in enumerate(self._tetrahedra_frequencies):
                self._tm.set_tetrahedra_omegas(frequencies)
                self._tm.run(self._frequency_points, value=self._value)
                iw = self._tm.get_integration_weight()
                self._integration_weights[:, ib] = iw
            self._integration_weights /= np.prod(self._mesh)
            self._grid_point_count += 1
            return self._integration_weights

    def next(self):
        return self.__next__()

    def get_integration_weights(self):
        return self._integration_weights

    def get_frequency_points(self):
        return self._frequency_points

    def set(self,
            value='I',
            division_number=201,
            frequency_points=None):
        self._grid_point_count = 0
        self._value = value
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency,
                                                 max_frequency,
                                                 division_number)
        else:
            self._frequency_points = frequency_points

        num_ir_grid_points = len(self._ir_grid_points)
        num_band = self._cell.get_number_of_atoms() * 3
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros((num_freqs, num_band),
                                             dtype='double')
        reciprocal_lattice = np.linalg.inv(self._cell.get_cell())
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()

    def _prepare(self):
        ir_gp_indices = {}
        for i, gp in enumerate(self._ir_grid_points):
            ir_gp_indices[gp] = i

        self._gp_ir_index = np.zeros_like(self._grid_mapping_table)
        for i, gp in enumerate(self._grid_mapping_table):
            self._gp_ir_index[i] = ir_gp_indices[gp]
        
    def _set_tetrahedra_frequencies(self, gp):
        self._tetrahedra_frequencies = get_tetrahedra_frequencies(
            gp,
            self._mesh,
            self._grid_address,
            self._relative_grid_address,
            self._gp_ir_index,
            self._frequencies,
            grid_order=self._grid_order,
            lang=self._lang)
Example #24
0
class TetrahedronMesh(object):
    def __init__(self,
                 cell,
                 frequencies,  # only at ir-grid-points
                 mesh,
                 grid_address,
                 grid_mapping_table,
                 ir_grid_points,
                 grid_order=None,
                 lang='C'):
        """Linear tetrahedron method on uniform mesh for phonons

        Parameters
        ----------
        cell : PhonopyAtoms
            Primitive cell used to calculate frequencies
        frequencies: ndarray
            Phonon frequences on grid points
            shape=(num_ir_grid_points, num_band)
            dtype='double'
        mesh : ndarray or list of int
            Mesh numbers for grids
            shape=(3,)
            dtype='intc'
        grid_address : ndarray
            Addresses of all grid points given by GridPoints class.
            shape=(prod(mesh), 3)
            dtype='intc'
        grid_mapping_table : ndarray
            Mapping of grid points to irreducible grid points given by
            GridPoints class.
            shape=(prod(mesh),)
            dtype='intc'
        ir_grid_points : ndarray
            Irreducible gird points given by GridPoints class.
            shape=(len(np.unique(grid_mapping_table)),)
            dtype='intc'
        grid_order : list of int, optional
            This controls how grid addresses are stored either C style or
            Fortran style.
        lang : str, 'C' or else, optional
            With 'C', C implementation is used. Otherwise Python implementation
            runs.

        """
        self._cell = cell
        self._frequencies = frequencies
        self._mesh = np.array(mesh, dtype='intc')
        self._grid_address = grid_address
        self._grid_mapping_table = grid_mapping_table
        self._lang = lang
        if lang == 'C':
            self._grid_order = None
        else:
            if grid_order is None:
                self._grid_order = [1, mesh[0], mesh[0] * mesh[1]]
            else:
                self._grid_order = grid_order
        self._ir_grid_points = np.array(ir_grid_points, dtype='intc')

        self._gp_ir_index = None

        self._tm = None
        self._tetrahedra_frequencies = None
        self._integration_weights = None
        self._relative_grid_address = None

        self._frequency_points = None
        self._value = None

        self._grid_point_count = 0

        self._prepare()

    def __iter__(self):
        return self

    def __next__(self):
        if self._grid_point_count == len(self._ir_grid_points):
            raise StopIteration
        else:
            gp = self._ir_grid_points[self._grid_point_count]
            self._set_tetrahedra_frequencies(gp)
            for ib, frequencies in enumerate(self._tetrahedra_frequencies):
                self._tm.set_tetrahedra_omegas(frequencies)
                self._tm.run(self._frequency_points, value=self._value)
                iw = self._tm.get_integration_weight()
                self._integration_weights[:, ib] = iw
            self._integration_weights /= np.prod(self._mesh)
            self._grid_point_count += 1
            return self._integration_weights

    def next(self):
        return self.__next__()

    def get_integration_weights(self):
        return self._integration_weights

    def get_frequency_points(self):
        return self._frequency_points

    def set(self,
            value='I',
            division_number=201,
            frequency_points=None):
        self._grid_point_count = 0
        self._value = value
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency,
                                                 max_frequency,
                                                 division_number,
                                                 dtype='double')
        else:
            self._frequency_points = np.array(frequency_points, dtype='double')

        num_band = self._cell.get_number_of_atoms() * 3
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros((num_freqs, num_band),
                                             dtype='double')
        reciprocal_lattice = np.linalg.inv(self._cell.get_cell())
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()

    def _prepare(self):
        ir_gp_indices = {}
        for i, gp in enumerate(self._ir_grid_points):
            ir_gp_indices[gp] = i

        self._gp_ir_index = np.zeros_like(self._grid_mapping_table)
        for i, gp in enumerate(self._grid_mapping_table):
            self._gp_ir_index[i] = ir_gp_indices[gp]

    def _set_tetrahedra_frequencies(self, gp):
        self._tetrahedra_frequencies = get_tetrahedra_frequencies(
            gp,
            self._mesh,
            self._grid_address,
            self._relative_grid_address,
            self._gp_ir_index,
            self._frequencies,
            grid_order=self._grid_order,
            lang=self._lang)
Example #25
0
class JointDos:
    def __init__(self,
                 mesh,
                 primitive,
                 supercell,
                 fc2,
                 nac_params=None,
                 sigma=None,
                 frequency_step=0.1,
                 frequency_factor_to_THz=VaspToTHz,
                 frequency_scale_factor=1.0,
                 is_nosym=False,
                 symprec=1e-5,
                 filename=None,
                 log_level=False,
                 lapack_zheev_uplo='L'):

        self._grid_point = None
        self._mesh = np.array(mesh, dtype='intc')
        self._primitive = primitive
        self._supercell = supercell
        self._fc2 = fc2
        self._nac_params = nac_params
        self.set_sigma(sigma)

        self._frequency_step = frequency_step
        self._frequency_factor_to_THz = frequency_factor_to_THz
        self._frequency_scale_factor = frequency_scale_factor
        self._is_nosym = is_nosym
        self._symprec = symprec
        self._filename = filename
        self._log_level = log_level
        self._lapack_zheev_uplo = lapack_zheev_uplo

        self._num_band = self._primitive.get_number_of_atoms() * 3
        self._reciprocal_lattice = np.linalg.inv(self._primitive.get_cell())
        self._set_dynamical_matrix()
        self._symmetry = Symmetry(primitive, symprec)

        self._tetrahedron_method = None
        self._phonon_done = None
        self._frequencies = None
        self._eigenvectors = None
        self._nac_q_direction = None
            
        self._joint_dos = None
        self._frequency_points = None

    def run(self):
        try:
            import anharmonic._phono3py as phono3c
            self._run_c()
        except ImportError:
            print "Joint density of states in python is not implemented."
            return None, None

    def get_joint_dos(self):
        return self._joint_dos

    def get_frequency_points(self):
        return self._frequency_points

    def get_phonons(self):
        return self._frequencies, self._eigenvectors, self._phonon_done
    
    def set_nac_q_direction(self, nac_q_direction=None):
        if nac_q_direction is not None:
            self._nac_q_direction = np.array(nac_q_direction, dtype='double')

    def set_sigma(self, sigma):
        if sigma is None:
            self._sigma = None
        else:
            self._sigma = float(sigma)

    def set_grid_point(self, grid_point):
        self._grid_point = grid_point
        self._set_triplets()
        num_grid = np.prod(len(self._grid_address))
        num_band = self._num_band
        if self._phonon_done is None:
            self._phonon_done = np.zeros(num_grid, dtype='byte')
            self._frequencies = np.zeros((num_grid, num_band), dtype='double')
            self._eigenvectors = np.zeros((num_grid, num_band, num_band),
                                          dtype='complex128')
            
        self._joint_dos = []
        self._frequency_points = []
        self._set_phonon(np.array([grid_point], dtype='intc'))

    def get_grid_address(self):
        return self._grid_address

    def get_triplets_at_q(self):
        return self._triplets_at_q, self._weights_at_q
        
    def _run_c(self, lang='Py'):
        if self._sigma is None:
            self._tetrahedron_method = TetrahedronMethod(
                self._reciprocal_lattice, mesh=self._mesh)
            if lang == 'C':
                self._run_c_tetrahedron_method()
            else:
                self._run_py_tetrahedron_method()
        else:
            self._run_smearing_method()

    def _run_c_tetrahedron_method(self):
        """
        This is not very faster than _run_c_tetrahedron_method and
        use much more memory space. So this function is not set as default.
        """
        import anharmonic._phono3py as phono3c
        thm = self._tetrahedron_method 
        unique_vertices = thm.get_unique_tetrahedra_vertices()
        for i, j in zip((1, 2), (1, -1)):
            neighboring_grid_points = np.zeros(
                len(unique_vertices) * len(self._triplets_at_q), dtype='intc')
            phono3c.neighboring_grid_points(
                neighboring_grid_points,
                self._triplets_at_q[:, i].flatten(),
                j * unique_vertices,
                self._mesh,
                self._grid_address,
                self._bz_map)
            self._set_phonon(np.unique(neighboring_grid_points))

        f_max = np.max(self._frequencies) * 2 + self._frequency_step / 10
        f_min = np.min(self._frequencies) * 2
        frequency_points = np.arange(f_min, f_max, self._frequency_step,
                                     dtype='double')

        num_band = self._num_band
        num_triplets = len(self._triplets_at_q)
        num_freq_points = len(frequency_points)
        g = np.zeros((num_triplets, num_freq_points, num_band, num_band, 2),
                     dtype='double')

        phono3c.triplets_integration_weights(
            g,
            frequency_points,
            thm.get_tetrahedra(),
            self._mesh,
            self._triplets_at_q,
            self._frequencies,
            self._grid_address,
            self._bz_map)

        jdos = np.tensordot(g, self._weights_at_q, axes=([0, 0]))
        jdos = jdos.sum(axis=1).sum(axis=1)[:, 0]
        self._joint_dos = jdos / np.prod(self._mesh)
        self._frequency_points = frequency_points
    
    def _run_py_tetrahedron_method(self):
        self._vertices = get_tetrahedra_vertices(
            self._tetrahedron_method.get_tetrahedra(),
            self._mesh,
            self._triplets_at_q,
            self._grid_address,
            self._bz_map)
        self._set_phonon(self._vertices.ravel())
        thm = self._tetrahedron_method
        f_max = np.max(self._frequencies) * 2 + self._frequency_step / 10
        f_min = np.min(self._frequencies) * 2
        freq_points = np.arange(f_min, f_max, self._frequency_step,
                                dtype='double')
        jdos = np.zeros_like(freq_points)
        for vertices, w in zip(self._vertices, self._weights_at_q):
            for i, j in list(np.ndindex(self._num_band, self._num_band)):
                f1 = self._frequencies[vertices[0], i]
                f2 = self._frequencies[vertices[1], j]
                thm.set_tetrahedra_omegas(f1 + f2)
                thm.run(freq_points)
                iw = thm.get_integration_weight()
                jdos += iw * w

        self._joint_dos = jdos / np.prod(self._mesh)
        self._frequency_points = freq_points

    def _run_smearing_method(self):
        import anharmonic._phono3py as phono3c

        self._set_phonon(self._triplets_at_q.ravel())
        f_max = np.max(self._frequencies) * 2 + self._sigma * 4
        f_min = np.min(self._frequencies) * 2 - self._sigma * 4
        freq_points = np.arange(f_min, f_max, self._frequency_step,
                                dtype='double')
        jdos = np.zeros_like(freq_points)
        phono3c.joint_dos(jdos,
                          freq_points,
                          self._triplets_at_q,
                          self._weights_at_q,
                          self._frequencies,
                          self._sigma)
        jdos /= np.prod(self._mesh)
        self._joint_dos = jdos
        self._frequency_points = freq_points
        
    def _set_dynamical_matrix(self):
        self._dm = get_dynamical_matrix(
            self._fc2,
            self._supercell,
            self._primitive,
            nac_params=self._nac_params,
            frequency_scale_factor=self._frequency_scale_factor,
            symprec=self._symprec)
        
    def _set_triplets(self):
        if self._is_nosym:
            if self._log_level:
                print "Triplets at q without considering symmetry"
                sys.stdout.flush()
            
            (self._triplets_at_q,
             self._weights_at_q,
             self._grid_address,
             self._bz_map) = get_nosym_triplets_at_q(
                 self._grid_point,
                 self._mesh,
                 self._reciprocal_lattice,
                 with_bz_map=True)
        else:
            (self._triplets_at_q,
             self._weights_at_q,
             self._grid_address,
             self._bz_map) = get_triplets_at_q(
                 self._grid_point,
                 self._mesh,
                 self._symmetry.get_pointgroup_operations(),
                 self._reciprocal_lattice)

    def _set_phonon(self, grid_points):
        set_phonon_c(self._dm,
                     self._frequencies,
                     self._eigenvectors,
                     self._phonon_done,
                     grid_points,
                     self._grid_address,
                     self._mesh,
                     self._frequency_factor_to_THz,
                     self._nac_q_direction,
                     self._lapack_zheev_uplo)
Example #26
0
class TetrahedronMesh:
    def __init__(self, mesh_object):
        self._mesh_object = mesh_object
        self._grid_address = None
        self._grid_order = None
        self._ir_grid_points = None
        self._ir_grid_weights = None
        self._gp_ir_index = None

        self._cell = None
        self._frequencies = None
        self._eigenvalues = None
        self._eigenvectors = None

        self._tm = None
        self._tetrahedra_frequencies = None
        self._integration_weights = None
        self._relative_grid_address = None

        self._total_dos = None
        self._partial_dos = None

        self._prepare()
        
    def get_total_dos(self):
        return self._total_dos

    def get_partial_dos(self):
        return self._partial_dos

    def get_integration_weights(self):
        return self._integration_weights

    def get_frequency_points(self):
        return self._frequency_points

    def run_at_frequencies(self,
                           value='I',
                           division_number=201,
                           frequency_points=None):                            
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency,
                                                 max_frequency,
                                                 division_number)
        else:
            self._frequency_points = frequency_points

        num_ir_grid_points = len(self._ir_grid_points)
        num_band = self._cell.get_number_of_atoms() * 3
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros(
            (num_freqs, num_band, num_ir_grid_points), dtype='double')

        reciprocal_lattice = np.linalg.inv(self._cell.get_cell())
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()

        for i, gp in enumerate(self._ir_grid_points):
            self._set_tetrahedra_frequencies(gp)
            for ib, frequencies in enumerate(self._tetrahedra_frequencies):
                self._tm.set_tetrahedra_omegas(frequencies)
                self._tm.run(self._frequency_points, value=value)
                iw = self._tm.get_integration_weight()
                self._integration_weights[:, ib, i] = iw

        self._integration_weights /= np.prod(self._mesh)

    def _prepare(self):
        mo = self._mesh_object
        self._cell = mo.get_dynamical_matrix().get_primitive()
        self._mesh = mo.get_mesh_numbers()
        self._grid_address = mo.get_grid_address()
        self._ir_grid_points = mo.get_ir_grid_points()
        self._ir_grid_weights = mo.get_weights()
        self._grid_order = [1, self._mesh[0], self._mesh[0] * self._mesh[1]]

        grid_mapping_table = mo.get_grid_mapping_table()
        self._gp_ir_index = np.zeros_like(grid_mapping_table)
        count = 0
        for i, gp in enumerate(grid_mapping_table):
            if i == gp:
                self._gp_ir_index[i] = count
                count += 1
            else:
                self._gp_ir_index[i] = self._gp_ir_index[grid_mapping_table[i]]

        self._frequencies = mo.get_frequencies()
        self._eigenvectors = mo.get_eigenvectors()

    def _set_tetrahedra_frequencies(self, gp):
        self._tetrahedra_frequencies = get_tetrahedra_frequencies(
            gp,
            self._mesh,
            self._grid_order,
            self._grid_address,
            self._relative_grid_address,
            self._gp_ir_index,
            self._frequencies)
Example #27
0
class TetrahedronMesh:
    def __init__(
            self,
            cell,
            frequencies,  # only at ir-grid-points
            mesh,
            grid_address,
            grid_mapping_table,
            grid_order=None):
        self._cell = cell
        self._frequencies = frequencies
        self._mesh = mesh
        self._grid_address = grid_address
        self._grid_mapping_table = grid_mapping_table
        if grid_order is None:
            self._grid_order = [1, mesh[0], mesh[0] * mesh[1]]
        else:
            self._grid_order = grid_order

        self._ir_grid_points = None
        self._gp_ir_index = None

        self._tm = None
        self._tetrahedra_frequencies = None
        self._integration_weights = None
        self._relative_grid_address = None

        self._prepare()

    def get_integration_weights(self):
        return self._integration_weights

    def get_frequency_points(self):
        return self._frequency_points

    def run_at_frequencies(self,
                           value='I',
                           division_number=201,
                           frequency_points=None):
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency, max_frequency,
                                                 division_number)
        else:
            self._frequency_points = frequency_points

        num_ir_grid_points = len(self._ir_grid_points)
        num_band = self._cell.get_number_of_atoms() * 3
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros(
            (num_freqs, num_band, num_ir_grid_points), dtype='double')

        reciprocal_lattice = np.linalg.inv(self._cell.get_cell())
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()

        for i, gp in enumerate(self._ir_grid_points):
            self._set_tetrahedra_frequencies(gp)
            for ib, frequencies in enumerate(self._tetrahedra_frequencies):
                self._tm.set_tetrahedra_omegas(frequencies)
                self._tm.run(self._frequency_points, value=value)
                iw = self._tm.get_integration_weight()
                self._integration_weights[:, ib, i] = iw

        self._integration_weights /= np.prod(self._mesh)

    def _prepare(self):
        (self._ir_grid_points,
         ir_grid_weights) = extract_ir_grid_points(self._grid_mapping_table)

        ir_gp_indices = {}
        for i, gp in enumerate(self._ir_grid_points):
            ir_gp_indices[gp] = i

        self._gp_ir_index = np.zeros_like(self._grid_mapping_table)
        for i, gp in enumerate(self._grid_mapping_table):
            self._gp_ir_index[i] = ir_gp_indices[gp]

    def _set_tetrahedra_frequencies(self, gp):
        self._tetrahedra_frequencies = get_tetrahedra_frequencies(
            gp, self._mesh, self._grid_order, self._grid_address,
            self._relative_grid_address, self._gp_ir_index, self._frequencies)
Example #28
0
class TetrahedronMesh(object):
    def __init__(self,
                 cell,
                 frequencies,  # only at ir-grid-points
                 mesh,
                 grid_address,
                 grid_mapping_table,
                 ir_grid_points,
                 grid_order=None,
                 lang='C'):
        """Linear tetrahedron method on uniform mesh for phonons

        Parameters
        ----------
        cell : PhonopyAtoms
            Primitive cell used to calculate frequencies
        frequencies: ndarray
            Phonon frequences on grid points
            shape=(num_ir_grid_points, num_band)
            dtype='double'
        mesh : ndarray or list of int
            Mesh numbers for grids
            shape=(3,)
            dtype='intc'
        grid_address : ndarray
            Addresses of all grid points given by GridPoints class.
            shape=(prod(mesh), 3)
            dtype='intc'
        grid_mapping_table : ndarray
            Mapping of grid points to irreducible grid points given by
            GridPoints class.
            shape=(prod(mesh),)
            dtype='uintp'
        ir_grid_points : ndarray
            Irreducible gird points given by GridPoints class.
            shape=(len(np.unique(grid_mapping_table)),)
            dtype='uintp'
        grid_order : list of int, optional
            This controls how grid addresses are stored either C style or
            Fortran style.
        lang : str, 'C' or else, optional
            With 'C', C implementation is used. Otherwise Python implementation
            runs.

        """
        self._cell = cell
        self._frequencies = frequencies
        self._mesh = np.array(mesh, dtype='intc')
        self._grid_address = grid_address
        self._grid_mapping_table = grid_mapping_table
        self._lang = lang
        if lang == 'C':
            self._grid_order = None
        else:
            if grid_order is None:
                self._grid_order = [1, mesh[0], mesh[0] * mesh[1]]
            else:
                self._grid_order = grid_order
        self._ir_grid_points = ir_grid_points

        self._gp_ir_index = None

        self._tm = None
        self._tetrahedra_frequencies = None
        self._integration_weights = None
        self._relative_grid_address = None

        self._frequency_points = None
        self._value = None

        self._grid_point_count = 0

        self._prepare()

    def __iter__(self):
        return self

    def __next__(self):
        if self._grid_point_count == len(self._ir_grid_points):
            raise StopIteration
        else:
            gp = self._ir_grid_points[self._grid_point_count]
            self._set_tetrahedra_frequencies(gp)
            for ib, frequencies in enumerate(self._tetrahedra_frequencies):
                self._tm.set_tetrahedra_omegas(frequencies)
                self._tm.run(self._frequency_points, value=self._value)
                iw = self._tm.get_integration_weight()
                self._integration_weights[:, ib] = iw
            self._integration_weights /= np.prod(self._mesh)
            self._grid_point_count += 1
            return self._integration_weights

    def next(self):
        return self.__next__()

    def get_integration_weights(self):
        return self._integration_weights

    def get_frequency_points(self):
        return self._frequency_points

    def set(self,
            value='I',
            division_number=201,
            frequency_points=None):
        self._grid_point_count = 0
        self._value = value
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency,
                                                 max_frequency,
                                                 division_number,
                                                 dtype='double')
        else:
            self._frequency_points = np.array(frequency_points, dtype='double')

        num_band = self._cell.get_number_of_atoms() * 3
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros((num_freqs, num_band),
                                             dtype='double')
        reciprocal_lattice = np.linalg.inv(self._cell.get_cell())
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()

    def _prepare(self):
        ir_gp_indices = {}
        for i, gp in enumerate(self._ir_grid_points):
            ir_gp_indices[gp] = i

        self._gp_ir_index = np.zeros_like(self._grid_mapping_table)
        for i, gp in enumerate(self._grid_mapping_table):
            self._gp_ir_index[i] = ir_gp_indices[gp]

    def _set_tetrahedra_frequencies(self, gp):
        self._tetrahedra_frequencies = get_tetrahedra_frequencies(
            gp,
            self._mesh,
            self._grid_address,
            self._relative_grid_address,
            self._gp_ir_index,
            self._frequencies,
            grid_order=self._grid_order,
            lang=self._lang)
Example #29
0
    def _run_py_tetrahedron_method(self):
        thm = TetrahedronMethod(self._reciprocal_lattice, mesh=self._mesh)
        self._vertices = get_tetrahedra_vertices(thm.get_tetrahedra(),
                                                 self._mesh,
                                                 self._triplets_at_q,
                                                 self._grid_address,
                                                 self._bz_map)
        self.run_phonon_solver(self._vertices.ravel())
        f_max = np.max(self._frequencies) * 2
        f_max *= 1.005
        f_min = 0
        self._set_uniform_frequency_points(f_min, f_max)

        num_freq_points = len(self._frequency_points)
        jdos = np.zeros((num_freq_points, 2), dtype='double')
        for vertices, w in zip(self._vertices, self._weights_at_q):
            for i, j in list(np.ndindex(self._num_band, self._num_band)):
                f1 = self._frequencies[vertices[0], i]
                f2 = self._frequencies[vertices[1], j]
                thm.set_tetrahedra_omegas(f1 + f2)
                thm.run(self._frequency_points)
                iw = thm.get_integration_weight()
                jdos[:, 1] += iw * w

                thm.set_tetrahedra_omegas(f1 - f2)
                thm.run(self._frequency_points)
                iw = thm.get_integration_weight()
                jdos[:, 0] += iw * w

                thm.set_tetrahedra_omegas(-f1 + f2)
                thm.run(self._frequency_points)
                iw = thm.get_integration_weight()
                jdos[:, 0] += iw * w

        self._joint_dos = jdos / np.prod(self._mesh)
Example #30
0
def _set_triplets_integration_weights_c(g,
                                        interaction,
                                        frequency_points = None,
                                        neighboring_phonons=True,
                                        triplets_at_q=None,
                                        band_indices=None,
                                        is_triplet_symmetry=False):
    import anharmonic._phono3py as phono3c
    if triplets_at_q == None:
        triplets_at_q = interaction.get_triplets_at_q()[0]
    if len(triplets_at_q) == 0:
        return
    reciprocal_lattice = np.linalg.inv(interaction.get_primitive().get_cell())
    mesh = interaction.get_mesh_numbers()
    thm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)

    grid_address = interaction.get_grid_address()
    bz_map = interaction.get_bz_map()
    if neighboring_phonons:
        unique_vertices = thm.get_unique_tetrahedra_vertices()
        for i in (1, 2, 0): # index inside a triplet
            for j in (1, -1):
                neighboring_grid_points = np.zeros(
                    len(unique_vertices) * len(np.unique(triplets_at_q[:, i])), dtype='intc')
                phono3c.neighboring_grid_points(
                neighboring_grid_points,
                np.unique(triplets_at_q[:, i]).astype("intc"),
                j * unique_vertices,
                mesh,
                grid_address,
                bz_map)
            interaction.set_phonons(np.unique(neighboring_grid_points))

    frequencies = interaction.get_phonons()[0]

    if len(np.where(mesh == 1)[0]) < 2:
        if band_indices is None:
            phono3c.triplets_integration_weights_fpoints(
                g,
                frequency_points,
                thm.get_tetrahedra().astype("intc").copy(),
                mesh,
                triplets_at_q,
                frequencies,
                grid_address,
                bz_map)
        else:
            phono3c.triplets_integration_weights(
                g,
                thm.get_tetrahedra().astype("intc").copy(),
                mesh,
                triplets_at_q,
                frequencies,
                np.array(band_indices, dtype='intc'),
                grid_address,
                bz_map,
                is_triplet_symmetry)
    else: # 1D case
        possible_shift = np.array((np.array(mesh) != 1), dtype='intc')
        relative_address = np.array([[[0, 0, 0],
                                      possible_shift],
                                     [[0, 0, 0],
                                      -possible_shift]], dtype="intc")
        if band_indices is None:
            phono3c.triplets_integration_weights_1D_fpoints(
                g,
                frequency_points,
                relative_address,
                mesh,
                triplets_at_q,
                frequencies,
                grid_address,
                bz_map)
        else:
            phono3c.triplets_integration_weights_1D(
                g,
                relative_address,
                mesh,
                triplets_at_q,
                frequencies,
                np.array(band_indices, dtype='intc'),
                grid_address,
                bz_map,
                is_triplet_symmetry)
Example #31
0
class Conductivity:
    def __init__(
            self,
            interaction,
            symmetry,
            grid_points=None,
            temperatures=np.arange(0, 1001, 10, dtype='double'),
            sigmas=[],
            is_isotope=False,
            mass_variances=None,
            mesh_divisors=None,
            coarse_mesh_shifts=None,
            boundary_mfp=None,  # in micrometre
            no_kappa_stars=False,
            gv_delta_q=None,  # finite difference for group veolocity
            log_level=0,
            is_band_connection=True,
            write_tecplot=False):
        self._pp = interaction
        self._collision = None  # has to be set derived class
        self._no_kappa_stars = no_kappa_stars
        self._gv_delta_q = gv_delta_q
        self._log_level = log_level
        self._sigmas = sigmas
        self._temperatures = temperatures
        self._primitive = self._pp.get_primitive()
        self._dm = self._pp.get_dynamical_matrix()
        self._frequency_factor_to_THz = self._pp.get_frequency_factor_to_THz()
        self._cutoff_frequency = self._pp.get_cutoff_frequency()
        self._boundary_mfp = boundary_mfp
        self._write_tecplot = write_tecplot
        self._set_mesh_numbers(mesh_divisors=mesh_divisors,
                               coarse_mesh_shifts=coarse_mesh_shifts)

        if (np.array(self._mesh) == 1).sum() > 1:
            if is_band_connection:
                interaction.set_phonons_all(
                    is_band_connection=is_band_connection)
        self._symmetry = symmetry
        self._bz_grid_address = None
        self._bz_to_pp_map = None
        self._coarse_mesh_shifts = None
        if self._no_kappa_stars:
            self._kpoint_operations = np.array([np.eye(3)], dtype="intc")
            self._mappings = np.arange(np.prod(self._mesh))
            self._rot_mappings = np.zeros(len(self._mappings), dtype="intc")
        else:
            self._kpoint_operations = get_kpoint_group(
                self._mesh, self._pp.get_point_group_operations())
            (self._mappings, self._rot_mappings) = get_mappings(
                self._mesh,
                self._pp.get_point_group_operations(),
                qpoints=np.array([0, 0, 0], dtype="double"))
        self._kpoint_group_sum_map = get_group_summation(
            self._kpoint_operations)
        self._kpoint_group_inv_map = get_group_inversion(
            self._kpoint_operations)
        rec_lat = np.linalg.inv(self._primitive.get_cell())
        self._rotations_cartesian = np.array([
            similarity_transformation(rec_lat, r)
            for r in self._kpoint_operations
        ],
                                             dtype='double')

        self._grid_points = None
        self._grid_weights = None
        self._grid_address = None
        self._ir_grid_points = None
        self._ir_grid_weights = None

        self._kappa = None
        self._kappa0 = None
        self._mode_kappa = None
        self._gamma = None
        self._read_gamma = False
        self._read_gamma_iso = False
        self._frequencies = None
        self._eigen_vectors = None
        self._gv = None
        self._gamma_iso = None
        volume = self._primitive.get_volume()
        self._conversion_factor = unit_to_WmK / volume
        self._kappa_factor = ite_unit_to_WmK / volume
        self._irr_index_mapping = np.where(
            np.unique(self._mappings) - self._mappings.reshape(-1, 1) == 0)[1]

        self._isotope = None
        self._mass_variances = None
        self._is_isotope = is_isotope
        if mass_variances is not None:
            self._is_isotope = True
        if self._is_isotope:
            self._set_isotope(mass_variances)
        self._grid_point_count = None
        self._degeneracies = None
        self._set_grid_properties(grid_points)
        self._bz_to_pp_map = self._pp.get_bz_to_pp_map()

    def get_mesh_divisors(self):
        return self._mesh_divisors

    def get_mesh_numbers(self):
        return self._mesh

    def get_group_velocities(self):
        return self._gv

    def get_mode_heat_capacities(self):
        pass

    def get_frequencies(self):
        return self._frequencies[self._grid_points]

    def get_qpoints(self):
        return self._qpoints

    def get_grid_points(self):
        return self._grid_points

    def get_grid_weights(self):
        return self._grid_weights

    def get_temperatures(self):
        return self._temperatures

    def set_temperature(self, i, temperature=None):
        self._itemp = i
        if self._temperatures is not None:
            self._temp = self._temperatures[i]
        else:
            self._temp = temperature

    def set_sigma(self, s, sigma=None):
        self._isigma = s
        if self._sigmas is not None:
            self._sigma = self._sigmas[s]
        else:
            self._sigma = sigma

    def set_temperatures(self, temperatures):
        self._temperatures = temperatures
        self._allocate_values()

    def set_gamma(self, gamma):
        self._gamma = gamma
        self._read_gamma = True

    def set_gamma_isotope(self, gamma_iso):
        self._gamma_iso = gamma_iso
        self._read_gamma_iso = True

    def get_gamma(self):
        return self._gamma

    def get_gamma_isotope(self):
        return self._gamma_iso

    def get_kappa(self):
        return self._kappa

    def get_kappa0(self):
        return self._kappa0

    def get_mode_kappa(self):
        return self._mode_kappa

    def get_sigmas(self):
        return self._sigmas

    def get_grid_point_count(self):
        return self._grid_point_count

    def set_pp_grid_points_all(self):
        self._pp.set_grid_points(self._grid_points)

    def _run_at_grid_point(self):
        """This has to be implemented in the derived class"""
        pass

    def _allocate_values(self):
        """This has to be implemented in the derived class"""
        pass

    def _calculate_kappa(self):
        """This has to be implemented in the derived class"""
        pass

    def _get_cv(self, freqs):

        cv = np.zeros((len(self._temperatures), len(freqs)), dtype='double')
        # T/freq has to be large enough to avoid divergence.
        # Otherwise just set 0.
        for i, f in enumerate(freqs):
            finite_t = (self._temperatures > f / 100)
            if f > self._cutoff_frequency:
                cv[:, i] = np.where(
                    finite_t,
                    get_mode_cv(np.where(finite_t, self._temperatures, 10000),
                                f * THzToEv), 0)
        return cv

    def set_rot_grid_points(self):
        num_rot = len(self._kpoint_operations)
        num_mesh_points = np.prod(self._mesh)
        self._rot_grid_points = np.zeros((num_rot, num_mesh_points),
                                         dtype='intc')

        for i in range(num_mesh_points):
            self._rot_grid_points[:, i] = get_grid_points_by_rotations(
                self._grid_address[i], self._kpoint_operations, self._mesh)

    def _set_grid_properties(self, grid_points):
        self._grid_address = self._pp.get_grid_address()

        if grid_points is not None:  # Specify grid points
            self._grid_points = reduce_grid_points(
                self._mesh_divisors,
                self._grid_address,
                grid_points,
                coarse_mesh_shifts=self._coarse_mesh_shifts)
            (self._ir_grid_points,
             self._ir_grid_weights) = self._get_ir_grid_points()
        elif self._no_kappa_stars:  # All grid points
            coarse_grid_address = get_grid_address(self._coarse_mesh)
            coarse_grid_points = np.arange(np.prod(self._coarse_mesh),
                                           dtype='intc')
            self._grid_points = from_coarse_to_dense_grid_points(
                self._mesh,
                self._mesh_divisors,
                coarse_grid_points,
                coarse_grid_address,
                coarse_mesh_shifts=self._coarse_mesh_shifts)
            self._grid_weights = np.ones(len(self._grid_points), dtype='intc')
            self._ir_grid_points = self._grid_points
            self._ir_grid_weights = self._grid_weights
        else:  # Automatic sampling
            self._grid_points, self._grid_weights = self._get_ir_grid_points()
            self._ir_grid_points = self._grid_points
            self._ir_grid_weights = self._grid_weights

        self._qpoints = np.array(self._grid_address[self._grid_points] /
                                 self._mesh.astype('double'),
                                 dtype='double',
                                 order='C')

        self._grid_point_count = 0
        self._pp.set_phonons(self._grid_points)
        self._frequencies = self._pp.get_phonons()[0][self._grid_points]
        self._eigen_vectors = self._pp.get_phonons()[1][self._grid_points]
        self._degeneracies = self._pp.get_degeneracy()[self._grid_points]
        if self._write_tecplot:
            self._dim = np.count_nonzero(np.array(self._mesh) > 1)
            #only dim=2 or 3 are implemented
            assert self._dim > 1, "The dimention of the given system is %d, but only dim=2 or 3 are implemented" % self._dim
            self.set_bz_grid_points()
            self.tetrahedra_specify()

    def _set_gamma_isotope_at_sigmas(self, i):
        for j, sigma in enumerate(self._sigmas):
            if self._log_level:
                print "Calculating Gamma of ph-isotope with",
                if sigma is None:
                    print "tetrahedron method"
                else:
                    print "sigma=%s" % sigma
            pp_freqs, pp_eigvecs, pp_phonon_done = self._pp.get_phonons()
            self._isotope.set_sigma(sigma)
            self._isotope.set_phonons(pp_freqs,
                                      pp_eigvecs,
                                      pp_phonon_done,
                                      dm=self._dm)
            gp = self._grid_points[i]
            self._isotope.set_grid_point(gp)
            self._isotope.run()
            self._gamma_iso[j, i] = self._isotope.get_gamma()

    def _set_mesh_numbers(self, mesh_divisors=None, coarse_mesh_shifts=None):
        self._mesh = self._pp.get_mesh_numbers()

        if mesh_divisors is None:
            self._mesh_divisors = np.array([1, 1, 1], dtype='intc')
        else:
            self._mesh_divisors = []
            for i, (m, n) in enumerate(zip(self._mesh, mesh_divisors)):
                if m % n == 0:
                    self._mesh_divisors.append(n)
                else:
                    self._mesh_divisors.append(1)
                    print("Mesh number %d for the " +
                          ["first", "second", "third"][i] +
                          " axis is not dividable by divisor %d.") % (m, n)
            self._mesh_divisors = np.array(self._mesh_divisors, dtype='intc')
            if coarse_mesh_shifts is None:
                self._coarse_mesh_shifts = [False, False, False]
            else:
                self._coarse_mesh_shifts = coarse_mesh_shifts
            for i in range(3):
                if (self._coarse_mesh_shifts[i]
                        and (self._mesh_divisors[i] % 2 != 0)):
                    print("Coarse grid along " +
                          ["first", "second", "third"][i] +
                          " axis can not be shifted. Set False.")
                    self._coarse_mesh_shifts[i] = False

        self._coarse_mesh = self._mesh / self._mesh_divisors

        if self._log_level:
            print("Lifetime sampling mesh: [ %d %d %d ]" %
                  tuple(self._mesh / self._mesh_divisors))

    def _get_ir_grid_points(self):
        if self._coarse_mesh_shifts is None:
            mesh_shifts = [False, False, False]
        else:
            mesh_shifts = self._coarse_mesh_shifts
        (coarse_grid_points, coarse_grid_weights,
         coarse_grid_address) = get_ir_grid_points(self._coarse_mesh,
                                                   self._primitive,
                                                   mesh_shifts=mesh_shifts)
        grid_points = from_coarse_to_dense_grid_points(
            self._mesh,
            self._mesh_divisors,
            coarse_grid_points,
            coarse_grid_address,
            coarse_mesh_shifts=self._coarse_mesh_shifts)
        grid_weights = coarse_grid_weights

        assert grid_weights.sum() == np.prod(self._mesh / self._mesh_divisors)

        return grid_points, grid_weights

    def set_bz_grid_points(self):
        self._bz_grid_address, self._bz_map , self._bz_to_pp_map= \
            relocate_BZ_grid_address(self._grid_address,
                                     self._mesh,
                                     np.linalg.inv(self._primitive.get_cell()),
                                     is_bz_map_to_orig=True)

    def tetrahedra_specify(self, lang="C"):
        reciprocal_lattice = np.linalg.inv(self._primitive.get_cell())
        mesh = self._mesh
        if self._dim == 3:
            self._tetra = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
            relative_address = self._tetra.get_tetrahedra()
            if lang == "C":
                self._unique_vertices = self.get_unique_tetrahedra_C(
                    relative_address)
            else:
                self._unique_vertices = self.get_unique_tetrahedra_py(
                    relative_address)
        elif self._dim == 2:
            self._tri = TriagonalMethod(reciprocal_lattice, mesh=mesh)
            relative_address = self._tri.get_triagonal()
            if lang == "C":
                self._unique_vertices = self.get_unique_triagonal_C(
                    relative_address)
            else:
                self._unique_vertices = self.get_unique_triagonal_py(
                    relative_address)

    def _set_isotope(self, mass_variances):
        if mass_variances is True:
            mv = None
        else:
            mv = mass_variances
        self._isotope = CollisionIso(
            self._mesh,
            self._primitive,
            mass_variances=mv,
            frequency_factor_to_THz=self._frequency_factor_to_THz,
            symprec=self._symmetry.get_symmetry_tolerance(),
            cutoff_frequency=self._cutoff_frequency,
            lapack_zheev_uplo=self._pp.get_lapack_zheev_uplo())
        self._mass_variances = self._isotope.get_mass_variances()

    def _set_gv(self, i):
        # Group velocity [num_freqs, 3]
        phonon = (self._frequencies[i], self._eigen_vectors[i],
                  self._degeneracies[i])
        gv = self._get_gv(self._qpoints[i], phonon=phonon)
        self._gv[i] = gv
        # if self._degeneracies is not None:
        #     deg = self._degeneracies[i]
        #     self._gv[i] = get_degenerate_property(deg, gv)

    def _get_gv(self, q, phonon=None):
        return get_group_velocity(
            q,
            self._dm,
            symmetry=self._symmetry,
            q_length=self._gv_delta_q,
            phonon=phonon,
            frequency_factor_to_THz=self._frequency_factor_to_THz)

    def _get_main_diagonal(self, i, j, k):
        num_band = self._primitive.get_number_of_atoms() * 3
        main_diagonal = self._gamma[j, k, i].copy()
        if self._gamma_iso is not None:
            main_diagonal += self._gamma_iso[j, i]
        if self._boundary_mfp is not None:
            main_diagonal += self._get_boundary_scattering(i)

        # if self._boundary_mfp is not None:
        #     for l in range(num_band):
        #         # Acoustic modes at Gamma are avoided.
        #         if i == 0 and l < 3:
        #             continue
        #         gv_norm = np.linalg.norm(self._gv[i, l])
        #         mean_free_path = (gv_norm * Angstrom * 1e6 /
        #                           (4 * np.pi * main_diagonal[l]))
        #         if mean_free_path > self._boundary_mfp:
        #             main_diagonal[l] = (
        #                 gv_norm / (4 * np.pi * self._boundary_mfp))

        return main_diagonal

    def _get_boundary_scattering(self, i):
        num_band = self._primitive.get_number_of_atoms() * 3
        g_boundary = np.zeros(num_band, dtype='double')
        for l in range(num_band):
            g_boundary[l] = (np.linalg.norm(self._gv[i, l]) * Angstrom * 1e6 /
                             (4 * np.pi * self._boundary_mfp))
        return g_boundary

    def _show_log_header(self, i):
        if self._log_level:
            gp = self._grid_points[i]
            print(
                "======================= Grid point %d (%d/%d) "
                "=======================" %
                (gp, i + 1, len(self._grid_points)))
            print "q-point: (%5.2f %5.2f %5.2f)" % tuple(self._qpoints[i])
            if self._boundary_mfp is not None:
                if self._boundary_mfp > 1000:
                    print("Boundary mean free path (millimetre): %.3f" %
                          (self._boundary_mfp / 1000.0))
                else:
                    print("Boundary mean free path (micrometre): %.5f" %
                          self._boundary_mfp)
            if self._is_isotope:
                print "Mass variance parameters:",
                print("%5.2e " * len(self._mass_variances)) % tuple(
                    self._mass_variances)

    def get_unique_tetrahedra_C(self, relative_address):
        import phonopy._spglib as spg
        num_expect = np.prod(self._mesh) * 6
        unique_vertices = np.zeros((num_expect, 4), dtype="intc")
        number_of_unique = spg.unique_tetrahedra(unique_vertices,
                                                 self._bz_grid_address,
                                                 self._bz_map,
                                                 relative_address, self._mesh)
        return unique_vertices[:number_of_unique]

    def get_unique_triagonal_C(self, relative_address):
        import phonopy._spglib as spg
        num_expect = np.prod(self._mesh) * 6
        unique_vertices = np.zeros((num_expect, 3), dtype="intc")
        number_of_unique = spg.unique_tetrahedra(unique_vertices,
                                                 self._bz_grid_address,
                                                 self._bz_map,
                                                 relative_address, self._mesh)
        return unique_vertices[:number_of_unique]

    def get_unique_triagonal_py(self, relative_address):
        assert np.count_nonzero(self._mesh > 1) == 2
        # bzmesh = np.extract(self._mesh>1, self._mesh) * 2
        bzmesh = self._mesh * 2
        bz_grid_order = [1, bzmesh[0], bzmesh[0] * bzmesh[1]]
        num_grids = len(self._bz_grid_address)
        unique_vertices = []
        for i in np.arange(num_grids):
            adrs = self._bz_grid_address[i] + relative_address
            bz_gp = np.dot(adrs % bzmesh, bz_grid_order)
            vgp = self._bz_map[bz_gp]
            for triag in vgp:
                if (triag == -1).any():
                    continue
                exists = False
                for element in unique_vertices:
                    if (triag == element).all():
                        exists = True
                        break
                if not exists:
                    unique_vertices.append(triag)
        return np.array(unique_vertices)

    def get_unique_tetrahedra_py(self, relative_address):
        bzmesh = self._mesh * 2
        bz_grid_order = [1, bzmesh[0], bzmesh[0] * bzmesh[1]]
        num_grids = len(self._bz_grid_address)
        unique_vertices = []
        for i in np.arange(num_grids):
            adrs = self._bz_grid_address[i] + relative_address
            bz_gp = np.dot(adrs % bzmesh, bz_grid_order)
            vgp = self._bz_map[bz_gp]
            for tetra in vgp:
                if (tetra == -1).any():
                    continue
                exists = False
                for element in unique_vertices:
                    if (tetra == element).all():
                        exists = True
                        break
                if not exists:
                    unique_vertices.append(tetra)
        return np.array(unique_vertices)

    def print_kappa(self, isigma=None, itemp=None):
        temperatures = self._temperatures
        directions = ['xx', 'yy', 'zz', 'xy', 'yz', 'zx']
        if self._log_level == 0:
            directions = self._kappa
        if self._log_level == 2:
            directions = directions
        if self._log_level == 0:
            directions = np.argmax(self._kappa, axis=-1)
        if self._log_level == 1:
            directions = ['xx', 'yy', 'zz']

        for i, sigma in enumerate(self._sigmas):
            if isigma is not None:
                if i != isigma:
                    continue
            kappa = self._kappa[i]
            band = ['band' + str(b + 1) for b in range(kappa.shape[2])]
            print "----------- Thermal conductivity (W/m-k) for",
            print "sigma=%s -----------" % sigma
            for j, direction in enumerate(directions):
                print "*direction:%s" % direction
                print("#%6s%10s" + " %9s" * len(band)) % (
                    ("T(K)", "Total") + tuple(band))
                for m, (t, k) in enumerate(
                        zip(temperatures, kappa[..., j].sum(axis=0))):
                    if itemp is not None:
                        if m != itemp:
                            continue
                    print("%7.1f%10.3f" + " %9.3f" * len(band)) % (
                        (t, k.sum()) + tuple(k))
                print
        sys.stdout.flush()
Example #32
0
    def _set_gamma_at_sigmas_lowmem(self, i):
        """Calculate gamma without storing ph-ph interaction strength.

        `svecs` and `multi` below must not be simply replaced by
        `self._pp.primitive.get_smallest_vectors()` because they must be in
        dense format as always so in Interaction class instance.
        `p2s`, `s2p`, and `masses` have to be also given from Interaction
        class instance.

        """
        band_indices = self._pp.band_indices
        (
            svecs,
            multi,
            p2s,
            s2p,
            masses,
        ) = self._pp.get_primitive_and_supercell_correspondence()
        fc3 = self._pp.fc3
        triplets_at_q, weights_at_q, _, _ = self._pp.get_triplets_at_q()
        symmetrize_fc3_q = 0

        if None in self._sigmas:
            thm = TetrahedronMethod(self._pp.bz_grid.microzone_lattice)

        # It is assumed that self._sigmas = [None].
        for j, sigma in enumerate(self._sigmas):
            self._collision.set_sigma(sigma)
            if self._is_N_U:
                collisions = np.zeros(
                    (2, len(self._temperatures), len(band_indices)),
                    dtype="double",
                    order="C",
                )
            else:
                collisions = np.zeros(
                    (len(self._temperatures), len(band_indices)),
                    dtype="double",
                    order="C",
                )
            import phono3py._phono3py as phono3c

            if sigma is None:
                phono3c.pp_collision(
                    collisions,
                    np.array(
                        np.dot(thm.get_tetrahedra(), self._pp.bz_grid.P.T),
                        dtype="int_",
                        order="C",
                    ),
                    self._frequencies,
                    self._eigenvectors,
                    triplets_at_q,
                    weights_at_q,
                    self._pp.bz_grid.addresses,
                    self._pp.bz_grid.gp_map,
                    self._pp.bz_grid.store_dense_gp_map * 1 + 1,
                    self._pp.bz_grid.D_diag,
                    self._pp.bz_grid.Q,
                    fc3,
                    svecs,
                    multi,
                    masses,
                    p2s,
                    s2p,
                    band_indices,
                    self._temperatures,
                    self._is_N_U * 1,
                    symmetrize_fc3_q,
                    self._pp.cutoff_frequency,
                )
            else:
                if self._sigma_cutoff is None:
                    sigma_cutoff = -1
                else:
                    sigma_cutoff = float(self._sigma_cutoff)
                phono3c.pp_collision_with_sigma(
                    collisions,
                    sigma,
                    sigma_cutoff,
                    self._frequencies,
                    self._eigenvectors,
                    triplets_at_q,
                    weights_at_q,
                    self._pp.bz_grid.addresses,
                    self._pp.bz_grid.D_diag,
                    self._pp.bz_grid.Q,
                    fc3,
                    svecs,
                    multi,
                    masses,
                    p2s,
                    s2p,
                    band_indices,
                    self._temperatures,
                    self._is_N_U * 1,
                    symmetrize_fc3_q,
                    self._pp.cutoff_frequency,
                )
            col_unit_conv = self._collision.unit_conversion_factor
            pp_unit_conv = self._pp.get_unit_conversion_factor()
            if self._is_N_U:
                col = collisions.sum(axis=0)
                col_N = collisions[0]
                col_U = collisions[1]
            else:
                col = collisions
            for k in range(len(self._temperatures)):
                self._gamma[j, k, i, :] = average_by_degeneracy(
                    col[k] * col_unit_conv * pp_unit_conv,
                    band_indices,
                    self._frequencies[self._grid_points[i]],
                )
                if self._is_N_U:
                    self._gamma_N[j, k, i, :] = average_by_degeneracy(
                        col_N[k] * col_unit_conv * pp_unit_conv,
                        band_indices,
                        self._frequencies[self._grid_points[i]],
                    )
                    self._gamma_U[j, k, i, :] = average_by_degeneracy(
                        col_U[k] * col_unit_conv * pp_unit_conv,
                        band_indices,
                        self._frequencies[self._grid_points[i]],
                    )
Example #33
0
class TetrahedronMesh:
    def __init__(self,
                 cell,
                 frequencies, # only at ir-grid-points
                 mesh,
                 grid_address,
                 grid_mapping_table,
                 ir_grid_points,
                 grid_order=None):
        self._cell = cell
        self._frequencies = frequencies
        self._mesh = mesh
        self._grid_address = grid_address
        self._grid_mapping_table = grid_mapping_table
        if grid_order is None:
            self._grid_order = [1, mesh[0], mesh[0] * mesh[1]]
        else:
            self._grid_order = grid_order
        self._ir_grid_points = ir_grid_points

        self._gp_ir_index = None

        self._tm = None
        self._tetrahedra_frequencies = None
        self._integration_weights = None
        self._relative_grid_address = None

        self._frequency_points = None
        self._value = None

        self._grid_point_count = 0

        self._prepare()
        
    def __iter__(self):
        return self
            
    def next(self):
        if self._grid_point_count == len(self._ir_grid_points):
            raise StopIteration
        else:
            gp = self._ir_grid_points[self._grid_point_count]
            self._set_tetrahedra_frequencies(gp)
            for ib, frequencies in enumerate(self._tetrahedra_frequencies):
                self._tm.set_tetrahedra_omegas(frequencies)
                self._tm.run(self._frequency_points, value=self._value)
                iw = self._tm.get_integration_weight()
                self._integration_weights[:, ib] = iw
            self._integration_weights /= np.prod(self._mesh)
            self._grid_point_count += 1
            return self._integration_weights

    def get_integration_weights(self):
        return self._integration_weights

    def get_frequency_points(self):
        return self._frequency_points

    def set(self,
            value='I',
            division_number=201,
            frequency_points=None):
        self._grid_point_count = 0
        self._value = value
        if frequency_points is None:
            max_frequency = np.amax(self._frequencies)
            min_frequency = np.amin(self._frequencies)
            self._frequency_points = np.linspace(min_frequency,
                                                 max_frequency,
                                                 division_number)
        else:
            self._frequency_points = frequency_points

        num_ir_grid_points = len(self._ir_grid_points)
        num_band = self._cell.get_number_of_atoms() * 3
        num_freqs = len(self._frequency_points)
        self._integration_weights = np.zeros((num_freqs, num_band),
                                             dtype='double')
        reciprocal_lattice = np.linalg.inv(self._cell.get_cell())
        self._tm = TetrahedronMethod(reciprocal_lattice, mesh=self._mesh)
        self._relative_grid_address = self._tm.get_tetrahedra()

    def _prepare(self):
        ir_gp_indices = {}
        for i, gp in enumerate(self._ir_grid_points):
            ir_gp_indices[gp] = i

        self._gp_ir_index = np.zeros_like(self._grid_mapping_table)
        for i, gp in enumerate(self._grid_mapping_table):
            self._gp_ir_index[i] = ir_gp_indices[gp]
        
    def _set_tetrahedra_frequencies(self, gp):
        self._tetrahedra_frequencies = get_tetrahedra_frequencies(
            gp,
            self._mesh,
            self._grid_order,
            self._grid_address,
            self._relative_grid_address,
            self._gp_ir_index,
            self._frequencies)
Example #34
0
def _set_triplets_integration_weights_py(g, interaction, frequency_points):
    reciprocal_lattice = np.linalg.inv(interaction.get_primitive().get_cell())
    mesh = interaction.get_mesh_numbers()
    thm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
    grid_address = interaction.get_grid_address()
    bz_map = interaction.get_bz_map()
    triplets_at_q = interaction.get_triplets_at_q()[0]
    unique_vertices = thm.get_unique_tetrahedra_vertices()
    tetrahedra_vertices = get_tetrahedra_vertices(
        thm.get_tetrahedra(),
        mesh,
        triplets_at_q,
        grid_address,
        bz_map)
    interaction.set_phonon(np.unique(tetrahedra_vertices))
    frequencies = interaction.get_phonons()[0]
    num_band = frequencies.shape[1]
    for i, vertices in enumerate(tetrahedra_vertices):
        for j, k in list(np.ndindex((num_band, num_band))):
            f1_v = frequencies[vertices[0], j]
            f2_v = frequencies[vertices[1], k]
            thm.set_tetrahedra_omegas(f1_v + f2_v)
            thm.run(frequency_points)
            g0 = thm.get_integration_weight()
            g[0, i, :, j, k] = g0
            thm.set_tetrahedra_omegas(-f1_v + f2_v)
            thm.run(frequency_points)
            g1 = thm.get_integration_weight()
            thm.set_tetrahedra_omegas(f1_v - f2_v)
            thm.run(frequency_points)
            g2 = thm.get_integration_weight()
            g[1, i, :, j, k] = g1 - g2
            if len(g) == 3:
                g[2, i, :, j, k] = g0 + g1 + g2
Example #35
0
    def _run_py_tetrahedron_method(self):
        thm = TetrahedronMethod(self._reciprocal_lattice, mesh=self._mesh)
        self._vertices = get_tetrahedra_vertices(
            thm.get_tetrahedra(),
            self._mesh,
            self._triplets_at_q,
            self._grid_address,
            self._bz_map)
        self.set_phonon(self._vertices.ravel())
        f_max = np.max(self._frequencies) * 2
        f_max *= 1.005
        f_min = 0
        self._set_frequency_points(f_min, f_max)

        num_freq_points = len(self._frequency_points)
        jdos = np.zeros((num_freq_points, 2), dtype='double')
        for vertices, w in zip(self._vertices, self._weights_at_q):
            for i, j in list(np.ndindex(self._num_band, self._num_band)):
                f1 = self._frequencies[vertices[0], i]
                f2 = self._frequencies[vertices[1], j]
                thm.set_tetrahedra_omegas(f1 + f2)
                thm.run(self._frequency_points)
                iw = thm.get_integration_weight()
                jdos[:, 0] += iw * w

                thm.set_tetrahedra_omegas(f1 - f2)
                thm.run(self._frequency_points)
                iw = thm.get_integration_weight()
                jdos[:, 1] += iw * w

                thm.set_tetrahedra_omegas(-f1 + f2)
                thm.run(self._frequency_points)
                iw = thm.get_integration_weight()
                jdos[:, 1] += iw * w

        self._joint_dos = jdos / np.prod(self._mesh)
Example #36
0
def _set_triplets_integration_weights_py(g, pp, frequency_points):
    """Python version of _set_triplets_integration_weights_c.

    Tetrahedron method engine is that implemented in phonopy written mainly in C.

    """
    thm = TetrahedronMethod(pp.bz_grid.microzone_lattice)
    triplets_at_q = pp.get_triplets_at_q()[0]
    tetrahedra_vertices = _get_tetrahedra_vertices(
        np.array(np.dot(thm.get_tetrahedra(), pp.bz_grid.P.T), dtype="int_", order="C"),
        triplets_at_q,
        pp.bz_grid,
    )
    pp.run_phonon_solver()
    frequencies = pp.get_phonons()[0]
    num_band = frequencies.shape[1]
    for i, vertices in enumerate(tetrahedra_vertices):
        for j, k in list(np.ndindex((num_band, num_band))):
            f1_v = frequencies[vertices[0], j]
            f2_v = frequencies[vertices[1], k]
            thm.set_tetrahedra_omegas(f1_v + f2_v)
            thm.run(frequency_points)
            g0 = thm.get_integration_weight()
            g[0, i, :, j, k] = g0
            thm.set_tetrahedra_omegas(-f1_v + f2_v)
            thm.run(frequency_points)
            g1 = thm.get_integration_weight()
            thm.set_tetrahedra_omegas(f1_v - f2_v)
            thm.run(frequency_points)
            g2 = thm.get_integration_weight()
            g[1, i, :, j, k] = g1 - g2
            if len(g) == 3:
                g[2, i, :, j, k] = g0 + g1 + g2