Example #1
0
def test_GridPoints_NaCl_with_rotations_fit_BZ(ph_nacl):
    rec_lat = np.linalg.inv(ph_nacl.primitive.cell)
    rotations = ph_nacl.primitive_symmetry.get_pointgroup_operations()
    mesh = [5, 5, 5]
    gpf = GridPoints(mesh, rec_lat, rotations=rotations,
                     fit_in_BZ=False)
    gpt = GridPoints(mesh, rec_lat, rotations=rotations,
                     fit_in_BZ=True)
    np.testing.assert_allclose(
        gpf.qpoints,
        [[0.0, 0.0, 0.0],
         [0.2, 0.0, 0.0],
         [0.4, 0.0, 0.0],
         [0.2, 0.2, 0.0],
         [0.4, 0.2, 0.0],
         [-0.4, 0.2, 0.0],
         [-0.2, 0.2, 0.0],
         [0.4, 0.4, 0.0],
         [-0.4, 0.4, 0.0],
         [-0.4, 0.4, 0.2]], atol=1e-8)
    np.testing.assert_allclose(
        gpt.qpoints,
        [[0.0, 0.0, 0.0],
         [0.2, 0.0, 0.0],
         [0.4, 0.0, 0.0],
         [0.2, 0.2, 0.0],
         [0.4, 0.2, 0.0],
         [-0.4, 0.2, 0.0],
         [-0.2, 0.2, 0.0],
         [0.4, 0.4, 0.0],
         [-0.4, -0.6, 0.0],
         [0.6, 0.4, 0.2]], atol=1e-8)
Example #2
0
    def __init__(
            self,
            dynamical_matrix,
            mesh,
            shift=None,
            is_time_reversal=True,
            is_mesh_symmetry=True,
            is_eigenvectors=False,
            is_gamma_center=False,
            rotations=None,  # Point group operations in real space
            factor=VaspToTHz):
        self._mesh = np.array(mesh, dtype='intc')
        self._is_eigenvectors = is_eigenvectors
        self._factor = factor
        self._cell = dynamical_matrix.get_primitive()
        self._dynamical_matrix = dynamical_matrix

        self._gp = GridPoints(self._mesh,
                              np.linalg.inv(self._cell.get_cell()),
                              q_mesh_shift=shift,
                              is_gamma_center=is_gamma_center,
                              is_time_reversal=(is_time_reversal
                                                and is_mesh_symmetry),
                              rotations=rotations,
                              is_mesh_symmetry=is_mesh_symmetry)

        self._qpoints = self._gp.get_ir_qpoints()
        self._weights = self._gp.get_ir_grid_weights()

        self._frequencies = None
        self._eigenvalues = None
        self._eigenvectors = None
Example #3
0
def test_GridPoints_SnO2_with_rotations_MP(ph_sno2):
    rec_lat = np.linalg.inv(ph_sno2.primitive.cell)
    rotations = ph_sno2.primitive_symmetry.get_pointgroup_operations()
    gp = GridPoints([4, 4, 4], rec_lat, rotations=rotations,
                    is_gamma_center=False)
    np.testing.assert_array_equal(
        gp.ir_grid_points, [0, 1, 5, 16, 17, 21])
    np.testing.assert_array_equal(gp.weights, [8, 16, 8, 8, 16, 8])
    np.testing.assert_array_equal(
        gp.grid_mapping_table,
        [0, 1, 1, 0, 1, 5, 5, 1, 1, 5,
         5, 1, 0, 1, 1, 0, 16, 17, 17, 16,
         17, 21, 21, 17, 17, 21, 21, 17, 16, 17,
         17, 16, 16, 17, 17, 16, 17, 21, 21, 17,
         17, 21, 21, 17, 16, 17, 17, 16, 0, 1,
         1, 0, 1, 5, 5, 1, 1, 5, 5, 1,
         0, 1, 1, 0])
    np.testing.assert_allclose(
        gp.qpoints,
        [[0.125, 0.125, 0.125],
         [0.375, 0.125, 0.125],
         [0.375, 0.375, 0.125],
         [0.125, 0.125, 0.375],
         [0.375, 0.125, 0.375],
         [0.375, 0.375, 0.375]], atol=1e-8)
Example #4
0
    def __init__(self,
                 dynamical_matrix,
                 mesh,
                 shift=None,
                 is_time_reversal=True,
                 is_mesh_symmetry=True,
                 is_eigenvectors=False,
                 is_gamma_center=False,
                 group_velocity=None,
                 rotations=None, # Point group operations in real space
                 factor=VaspToTHz):
        self._mesh = np.array(mesh, dtype='intc')
        self._is_eigenvectors = is_eigenvectors
        self._factor = factor
        self._cell = dynamical_matrix.get_primitive()
        self._dynamical_matrix = dynamical_matrix

        self._gp = GridPoints(self._mesh,
                              np.linalg.inv(self._cell.get_cell()),
                              q_mesh_shift=shift,
                              is_gamma_center=is_gamma_center,
                              is_time_reversal=is_time_reversal,
                              rotations=rotations,
                              is_mesh_symmetry=is_mesh_symmetry)
        self._qpoints = self._gp.get_ir_qpoints()
        self._weights = self._gp.get_ir_grid_weights()

        self._frequencies = None
        self._eigenvalues = None
        self._eigenvectors = None
        self._set_phonon()

        self._group_velocities = None
        if group_velocity is not None:
            self._set_group_velocities(group_velocity)
Example #5
0
def test_GridPoints_NaCl_with_rotations(ph_nacl):
    rec_lat = np.linalg.inv(ph_nacl.primitive.cell)
    rotations = ph_nacl.primitive_symmetry.get_pointgroup_operations()
    gp = GridPoints([4, 4, 4], rec_lat, rotations=rotations)
    np.testing.assert_array_equal(
        gp.ir_grid_points, [0, 1, 2, 5, 6, 7, 10, 27])
    np.testing.assert_array_equal(gp.weights, [1, 8, 4, 6, 24, 12, 3, 6])
    np.testing.assert_array_equal(
        gp.grid_mapping_table,
        [0, 1, 2, 1, 1, 5, 6, 7, 2, 6,
         10, 6, 1, 7, 6, 5, 1, 5, 6, 7,
         5, 1, 7, 6, 6, 7, 6, 27, 7, 6,
         27, 6, 2, 6, 10, 6, 6, 7, 6, 27,
         10, 6, 2, 6, 6, 27, 6, 7, 1, 7,
         6, 5, 7, 6, 27, 6, 6, 27, 6, 7,
         5, 6, 7, 1])
    np.testing.assert_allclose(
        gp.qpoints,
        [[0.0, 0.0, 0.0],
         [0.25, 0.0, 0.0],
         [0.5, 0.0, 0.0],
         [0.25, 0.25, 0.0],
         [0.5, 0.25, 0.0],
         [-0.25, 0.25, 0.0],
         [0.5, 0.5, 0.0],
         [-0.25, 0.5, 0.25]], atol=1e-8)
Example #6
0
    def __init__(self,
                 dynamical_matrix,
                 cell,
                 mesh,
                 shift=None,
                 is_time_reversal=False,
                 is_mesh_symmetry=True,
                 is_eigenvectors=False,
                 is_band_connection=False,
                 is_gamma_center=False,
                 group_velocity=None,
                 factor=VaspToTHz,
                 symprec=1e-5):
        self._mesh = np.array(mesh)
        self._is_band_connection=is_band_connection
        self._band_order = None
        self._is_eigenvectors = is_eigenvectors
        self._factor = factor
        self._cell = cell
        self._dynamical_matrix = dynamical_matrix
        # self._qpoints, self._weights = get_qpoints(self._mesh,
        #                                            self._cell,
        #                                            shift,
        #                                            is_gamma_center,
        #                                            is_time_reversal,
        #                                            symprec,
        #                                            is_symmetry)
        rotations  = Symmetry(self._cell).get_pointgroup_operations()
        self._gp = GridPoints(self._mesh,
                              np.linalg.inv(self._cell.get_cell()),
                              q_mesh_shift=shift,
                              is_gamma_center=is_gamma_center,
                              is_time_reversal=is_time_reversal,
                              rotations=rotations,
                              is_mesh_symmetry=is_mesh_symmetry)
        self._qpoints = self._gp.get_ir_qpoints()
        self._weights = self._gp.get_ir_grid_weights()

        self._eigenvalues = None
        self._eigenvectors = None
        self._set_eigenvalues()
        if self._is_band_connection:
            self._set_band_connection()

        self._group_velocities = None
        if group_velocity is not None:
            self._set_group_velocities(group_velocity)
Example #7
0
 def testGridPoints(self):
     gp = GridPoints([11, 11, 11], [[-1, 1, 1], [1, -1, 1], [1, 1, -1]])
     self.assertTrue((gp.grid_address == gp.get_grid_address()).all())
     self.assertTrue((gp.ir_grid_points == gp.get_ir_grid_points()).all())
     np.testing.assert_allclose(gp.qpoints, gp.get_ir_qpoints())
     self.assertTrue((gp.weights == gp.get_ir_grid_weights()).all())
     self.assertTrue(
         (gp.grid_mapping_table == gp.get_grid_mapping_table()).all())
Example #8
0
def test_GridPoints():
    """Test of GridPoints."""
    gp = GridPoints([2, 3, 4], [[-1, 1, 1], [1, -1, 1], [1, 1, -1]])

    assert gp.ir_grid_points.dtype == np.dtype("int_")
    assert gp.weights.dtype == np.dtype("int_")
    assert gp.grid_mapping_table.dtype == np.dtype("int_")
    assert gp.grid_address.dtype == np.dtype("intc")
    assert gp.mesh_numbers.dtype == np.dtype("intc")
    assert gp.reciprocal_lattice.dtype == np.dtype("double")
    assert gp.qpoints.dtype == np.dtype("double")

    np.testing.assert_array_equal(gp.grid_address, ga234)
Example #9
0
 def testGridPoints(self):
     gp = GridPoints([11, 11, 11],
                     [[-1, 1, 1], [1, -1, 1], [1, 1, -1]])
     self.assertTrue((gp.grid_address == gp.get_grid_address()).all())
     self.assertTrue((gp.ir_grid_points == gp.get_ir_grid_points()).all())
     np.testing.assert_allclose(gp.qpoints, gp.get_ir_qpoints())
     self.assertTrue((gp.weights == gp.get_ir_grid_weights()).all())
     self.assertTrue((gp.grid_mapping_table ==
                      gp.get_grid_mapping_table()).all())
Example #10
0
def test_GridPoints_NaCl_with_rotations_fit_BZ(ph_nacl: Phonopy, fit_in_BZ):
    """Test of GridPoints with rotations from NaCl and fit_in_BZ."""
    rec_lat = np.linalg.inv(ph_nacl.primitive.cell)
    rotations = ph_nacl.primitive_symmetry.pointgroup_operations
    mesh = [5, 5, 5]
    gpts = GridPoints(mesh, rec_lat, rotations=rotations, fit_in_BZ=fit_in_BZ)
    if fit_in_BZ:
        np.testing.assert_allclose(
            gpts.qpoints,
            [
                [0.0, 0.0, 0.0],
                [0.2, 0.0, 0.0],
                [0.4, 0.0, 0.0],
                [0.2, 0.2, 0.0],
                [0.4, 0.2, 0.0],
                [-0.4, 0.2, 0.0],
                [-0.2, 0.2, 0.0],
                [0.4, 0.4, 0.0],
                [-0.4, -0.6, 0.0],
                [0.6, 0.4, 0.2],
            ],
            atol=1e-8,
        )
    else:
        np.testing.assert_allclose(
            gpts.qpoints,
            [
                [0.0, 0.0, 0.0],
                [0.2, 0.0, 0.0],
                [0.4, 0.0, 0.0],
                [0.2, 0.2, 0.0],
                [0.4, 0.2, 0.0],
                [-0.4, 0.2, 0.0],
                [-0.2, 0.2, 0.0],
                [0.4, 0.4, 0.0],
                [-0.4, 0.4, 0.0],
                [-0.4, 0.4, 0.2],
            ],
            atol=1e-8,
        )
Example #11
0
def test_GridPoints_SnO2_with_rotations(ph_sno2):
    rec_lat = np.linalg.inv(ph_sno2.primitive.cell)
    rotations = ph_sno2.primitive_symmetry.get_pointgroup_operations()
    gp = GridPoints([4, 4, 4], rec_lat, rotations=rotations)
    np.testing.assert_array_equal(
        gp.ir_grid_points,
        [0, 1, 2, 5, 6, 10, 16, 17, 18, 21, 22, 26, 32, 33, 34, 37, 38, 42])
    np.testing.assert_array_equal(
        gp.weights,
        [1, 4, 2, 4, 4, 1, 2, 8, 4, 8, 8, 2, 1, 4, 2, 4, 4, 1])
    np.testing.assert_array_equal(
        gp.grid_mapping_table,
        [0, 1, 2, 1, 1, 5, 6, 5, 2, 6,
         10, 6, 1, 5, 6, 5, 16, 17, 18, 17,
         17, 21, 22, 21, 18, 22, 26, 22, 17, 21,
         22, 21, 32, 33, 34, 33, 33, 37, 38, 37,
         34, 38, 42, 38, 33, 37, 38, 37, 16, 17,
         18, 17, 17, 21, 22, 21, 18, 22, 26, 22,
         17, 21, 22, 21])
    np.testing.assert_allclose(
        gp.qpoints,
        [[0.0, 0.0, 0.0],
         [0.25, 0.0, 0.0],
         [0.5, 0.0, 0.0],
         [0.25, 0.25, 0.0],
         [0.5, 0.25, 0.0],
         [0.5, 0.5, 0.0],
         [0.0, 0.0, 0.25],
         [0.25, 0.0, 0.25],
         [0.5, 0.0, 0.25],
         [0.25, 0.25, 0.25],
         [0.5, 0.25, 0.25],
         [0.5, 0.5, 0.25],
         [0.0, 0.0, 0.5],
         [0.25, 0.0, 0.5],
         [0.5, 0.0, 0.5],
         [0.25, 0.25, 0.5],
         [0.5, 0.25, 0.5],
         [0.5, 0.5, 0.5]], atol=1e-8)
Example #12
0
    def __init__(
        self,
        dynamical_matrix: DynamicalMatrix,
        mesh,
        shift=None,
        is_time_reversal=True,
        is_mesh_symmetry=True,
        with_eigenvectors=False,
        is_gamma_center=False,
        rotations=None,  # Point group operations in real space
        factor=VaspToTHz,
    ):
        """Init method."""
        self._mesh = np.array(mesh, dtype="intc")
        self._with_eigenvectors = with_eigenvectors
        self._factor = factor
        self._cell = dynamical_matrix.primitive
        self._dynamical_matrix = dynamical_matrix

        self._gp = GridPoints(
            self._mesh,
            np.linalg.inv(self._cell.cell),
            q_mesh_shift=shift,
            is_gamma_center=is_gamma_center,
            is_time_reversal=(is_time_reversal and is_mesh_symmetry),
            rotations=rotations,
            is_mesh_symmetry=is_mesh_symmetry,
        )

        self._qpoints = self._gp.qpoints
        self._weights = self._gp.weights

        self._frequencies = None
        self._eigenvectors = None

        self._q_count = 0
Example #13
0
class Mesh:
    def __init__(self,
                 dynamical_matrix,
                 mesh,
                 shift=None,
                 is_time_reversal=True,
                 is_mesh_symmetry=True,
                 is_eigenvectors=False,
                 is_gamma_center=False,
                 group_velocity=None,
                 rotations=None, # Point group operations in real space
                 factor=VaspToTHz,
                 use_lapack_solver=False):

        self._mesh = np.array(mesh, dtype='intc')
        self._is_eigenvectors = is_eigenvectors
        self._factor = factor
        self._cell = dynamical_matrix.get_primitive()
        self._dynamical_matrix = dynamical_matrix
        self._use_lapack_solver = use_lapack_solver

        self._gp = GridPoints(self._mesh,
                              np.linalg.inv(self._cell.get_cell()),
                              q_mesh_shift=shift,
                              is_gamma_center=is_gamma_center,
                              is_time_reversal=is_time_reversal,
                              rotations=rotations,
                              is_mesh_symmetry=is_mesh_symmetry)

        self._qpoints = self._gp.get_ir_qpoints()
        self._weights = self._gp.get_ir_grid_weights()

        self._frequencies = None
        self._eigenvalues = None
        self._eigenvectors = None
        self._set_phonon()

        self._group_velocities = None
        if group_velocity is not None:
            self._set_group_velocities(group_velocity)

    def get_dynamical_matrix(self):
        return self._dynamical_matrix
        
    def get_mesh_numbers(self):
        return self._mesh
        
    def get_qpoints(self):
        return self._qpoints

    def get_weights(self):
        return self._weights

    def get_grid_address(self):
        return self._gp.get_grid_address()

    def get_ir_grid_points(self):
        return self._gp.get_ir_grid_points()
    
    def get_grid_mapping_table(self):
        return self._gp.get_grid_mapping_table()

    def get_eigenvalues(self):
        return self._eigenvalues

    def get_frequencies(self):
        return self._frequencies

    def get_group_velocities(self):
        return self._group_velocities
    
    def get_eigenvectors(self):
        """
        Eigenvectors is a numpy array of three dimension.
        The first index runs through q-points.
        In the second and third indices, eigenvectors obtained
        using numpy.linalg.eigh are stored.
        
        The third index corresponds to the eigenvalue's index.
        The second index is for atoms [x1, y1, z1, x2, y2, z2, ...].
        """
        return self._eigenvectors

    def write_hdf5(self):
        import h5py
        with h5py.File('mesh.hdf5', 'w') as w:
            w.create_dataset('mesh', data=self._mesh)
            w.create_dataset('qpoint', data=self._qpoints)
            w.create_dataset('weight', data=self._weights)
            w.create_dataset('frequency', data=self._frequencies)
            if self._eigenvectors is not None:
                w.create_dataset('eigenvector', data=self._eigenvectors)
            if self._group_velocities is not None:
                w.create_dataset('group_velocity', data=self._group_velocities)

    def write_yaml(self):
        w = open('mesh.yaml', 'w')
        eigenvalues = self._eigenvalues
        natom = self._cell.get_number_of_atoms()
        rec_lattice = np.linalg.inv(self._cell.get_cell()) # column vectors
        supercell = self._dynamical_matrix.get_supercell()
        smat = supercell.get_supercell_matrix()
        pmat = self._cell.get_primitive_matrix()
        tmat = np.rint(np.dot(np.linalg.inv(pmat), smat)).astype(int)


        w.write("mesh: [ %5d, %5d, %5d ]\n" % tuple(self._mesh))
        w.write("nqpoint: %-7d\n" % self._qpoints.shape[0])
        w.write("reciprocal_lattice:\n")
        for vec, axis in zip(rec_lattice.T, ('a*', 'b*', 'c*')):
            w.write("- [ %12.8f, %12.8f, %12.8f ] # %2s\n" %
                    (tuple(vec) + (axis,)))
        w.write("natom:   %-7d\n" % natom)
        w.write(str(PhonopyAtoms(atoms=self._cell)))
        w.write("\n")
        w.write("supercell_matrix:\n")
        for v in tmat:
            w.write("- [ %4d, %4d, %4d ]\n" % tuple(v))

        w.write("\n")
        w.write("phonon:\n")

        for i, q in enumerate(self._qpoints):
            w.write("- q-position: [ %12.7f, %12.7f, %12.7f ]\n" % tuple(q))
            w.write("  weight: %-5d\n" % self._weights[i])
            w.write("  band:\n")

            for j, freq in enumerate(self._frequencies[i]):
                w.write("  - # %d\n" % (j + 1))
                w.write("    frequency:  %15.10f\n" % freq)

                if self._group_velocities is not None:
                    w.write("    group_velocity: ")
                    w.write("[ %13.7f, %13.7f, %13.7f ]\n" %
                            tuple(self._group_velocities[i, j]))

                if self._is_eigenvectors:
                    w.write("    eigenvector:\n")
                    for k in range(natom):
                        w.write("    - # atom %d\n" % (k+1))
                        for l in (0,1,2):
                            w.write("      - [ %17.14f, %17.14f ]\n" %
                                    (self._eigenvectors[i,k*3+l,j].real,
                                     self._eigenvectors[i,k*3+l,j].imag))
            w.write("\n")

    def _set_phonon(self):
        num_band = self._cell.get_number_of_atoms() * 3
        num_qpoints = len(self._qpoints)

        self._eigenvalues = np.zeros((num_qpoints, num_band), dtype='double')
        self._frequencies = np.zeros_like(self._eigenvalues)
        if self._is_eigenvectors or self._use_lapack_solver:
            self._eigenvectors = np.zeros(
                (num_qpoints, num_band, num_band,), dtype='complex128')

        if self._use_lapack_solver:
            from phonopy.phonon.solver import get_phonons_at_qpoints
            get_phonons_at_qpoints(self._frequencies,
                                   self._eigenvectors,
                                   self._dynamical_matrix,
                                   self._qpoints,
                                   self._factor,
                                   nac_q_direction=None,
                                   lapack_zheev_uplo='L')
            self._eigenvalues = np.array(self._frequencies ** 2 *
                                         np.sign(self._frequencies),
                                         dtype='double',
                                         order='C') / self._factor ** 2
            if not self._is_eigenvectors:
                self._eigenvalues = None
        else:
            for i, q in enumerate(self._qpoints):
                self._dynamical_matrix.set_dynamical_matrix(q)
                dm = self._dynamical_matrix.get_dynamical_matrix()
                if self._is_eigenvectors:
                    eigvals, self._eigenvectors[i] = np.linalg.eigh(dm)
                    self._eigenvalues[i] = eigvals.real
                else:
                    self._eigenvalues[i] = np.linalg.eigvalsh(dm).real
            self._frequencies = np.array(np.sqrt(abs(self._eigenvalues)) *
                                         np.sign(self._eigenvalues),
                                         dtype='double',
                                         order='C') * self._factor


    def _set_group_velocities(self, group_velocity):
        group_velocity.set_q_points(self._qpoints)
        self._group_velocities = group_velocity.get_group_velocity()
Example #14
0
    def __init__(self,
                 dynamical_matrix,
                 unitcell_ideal,
                 primitive_matrix_ideal,
                 mesh,
                 shift=None,
                 is_time_reversal=True,
                 is_mesh_symmetry=True,
                 is_eigenvectors=False,
                 is_gamma_center=False,
                 star="none",
                 group_velocity=None,
                 rotations=None, # Point group operations in real space
                 factor=VaspToTHz,
                 use_lapack_solver=False,
                 mode="eigenvector"):

        self._mesh = np.array(mesh, dtype='intc')
        self._is_eigenvectors = is_eigenvectors
        self._factor = factor

        primitive_ideal_wrt_unitcell = (
            get_primitive(unitcell_ideal, primitive_matrix_ideal))
        self._cell = primitive_ideal_wrt_unitcell

        # ._dynamical_matrix must be assigned for calculating DOS
        # using the tetrahedron method.
        # In the "DOS", this is used to get "primitive".
        # In the "TetrahedronMesh", this is used just as the "Atoms".
        # Currently, we must not use the tetrahedron method,
        # because now we do not give the primitive but the unitcell for the
        # self._dynamical_matrix.
        self._dynamical_matrix = dynamical_matrix
        self._use_lapack_solver = use_lapack_solver

        self._gp = GridPoints(self._mesh,
                              np.linalg.inv(self._cell.get_cell()),
                              q_mesh_shift=shift,
                              is_gamma_center=is_gamma_center,
                              is_time_reversal=is_time_reversal,
                              rotations=rotations,
                              is_mesh_symmetry=is_mesh_symmetry)

        self._qpoints = self._gp.get_ir_qpoints()
        self._weights = self._gp.get_ir_grid_weights()

        self._star = star

        self._eigenstates_unfolding = Eigenstates(
            dynamical_matrix,
            unitcell_ideal,
            primitive_matrix_ideal,
            mode=mode,
            star=star,
            verbose=False)

        self._frequencies = None
        self._eigenvalues = None
        self._eigenvectors = None
        self._set_phonon()

        self._group_velocities = None
        if group_velocity is not None:
            self._set_group_velocities(group_velocity)
Example #15
0
class MeshUnfolding(Mesh):
    def __init__(self,
                 dynamical_matrix,
                 unitcell_ideal,
                 primitive_matrix_ideal,
                 mesh,
                 shift=None,
                 is_time_reversal=True,
                 is_mesh_symmetry=True,
                 is_eigenvectors=False,
                 is_gamma_center=False,
                 star="none",
                 group_velocity=None,
                 rotations=None, # Point group operations in real space
                 factor=VaspToTHz,
                 use_lapack_solver=False,
                 mode="eigenvector"):

        self._mesh = np.array(mesh, dtype='intc')
        self._is_eigenvectors = is_eigenvectors
        self._factor = factor

        primitive_ideal_wrt_unitcell = (
            get_primitive(unitcell_ideal, primitive_matrix_ideal))
        self._cell = primitive_ideal_wrt_unitcell

        # ._dynamical_matrix must be assigned for calculating DOS
        # using the tetrahedron method.
        # In the "DOS", this is used to get "primitive".
        # In the "TetrahedronMesh", this is used just as the "Atoms".
        # Currently, we must not use the tetrahedron method,
        # because now we do not give the primitive but the unitcell for the
        # self._dynamical_matrix.
        self._dynamical_matrix = dynamical_matrix
        self._use_lapack_solver = use_lapack_solver

        self._gp = GridPoints(self._mesh,
                              np.linalg.inv(self._cell.get_cell()),
                              q_mesh_shift=shift,
                              is_gamma_center=is_gamma_center,
                              is_time_reversal=is_time_reversal,
                              rotations=rotations,
                              is_mesh_symmetry=is_mesh_symmetry)

        self._qpoints = self._gp.get_ir_qpoints()
        self._weights = self._gp.get_ir_grid_weights()

        self._star = star

        self._eigenstates_unfolding = Eigenstates(
            dynamical_matrix,
            unitcell_ideal,
            primitive_matrix_ideal,
            mode=mode,
            star=star,
            verbose=False)

        self._frequencies = None
        self._eigenvalues = None
        self._eigenvectors = None
        self._set_phonon()

        self._group_velocities = None
        if group_velocity is not None:
            self._set_group_velocities(group_velocity)

    def get_pr_weights(self):
        return self._pr_weights

    def write_yaml(self):
        w = open('mesh.yaml', 'w')
        eigenvalues = self._eigenvalues
        natom = self._cell.get_number_of_atoms()
        lattice = np.linalg.inv(self._cell.get_cell()) # column vectors
        w.write("mesh: [ %5d, %5d, %5d ]\n" % tuple(self._mesh))
        w.write("nqpoint: %-7d\n" % self._qpoints.shape[0])
        w.write("natom:   %-7d\n" % natom)
        w.write("reciprocal_lattice:\n")
        for vec, axis in zip(lattice.T, ('a*', 'b*', 'c*')):
            w.write("- [ %12.8f, %12.8f, %12.8f ] # %2s\n" %
                    (tuple(vec) + (axis,)))
        w.write("phonon:\n")

        for i, q in enumerate(self._qpoints):
            w.write("- q-position: [ %12.7f, %12.7f, %12.7f ]\n" % tuple(q))
            w.write("  weight: %-5d\n" % self._weights[i])
            w.write("  band:\n")

            for j, freq in enumerate(self._frequencies[i]):
                w.write("  - # %d\n" % (j + 1))
                w.write("    frequency:  %15.10f\n" % freq)
                w.write("    pr_weight:  %15.10f\n" % self._pr_weights[i, j])

                if self._group_velocities is not None:
                    w.write("    group_velocity: ")
                    w.write("[ %13.7f, %13.7f, %13.7f ]\n" %
                            tuple(self._group_velocities[i, j]))

                if self._is_eigenvectors:
                    w.write("    eigenvector:\n")
                    for k in range(natom):
                        w.write("    - # atom %d\n" % (k+1))
                        for l in (0,1,2):
                            w.write("      - [ %17.14f, %17.14f ]\n" %
                                    (self._eigenvectors[i,k*3+l,j].real,
                                     self._eigenvectors[i,k*3+l,j].imag))
            w.write("\n")

    def _set_phonon(self):
        # For the unfolding method.
        # num_band = self._cell.get_number_of_atoms() * 3
        cell = self._dynamical_matrix.get_primitive()
        num_band = cell.get_number_of_atoms() * 3
        num_qpoints = len(self._qpoints)

        self._eigenvalues = np.zeros((num_qpoints, num_band), dtype='double')
        self._frequencies = np.zeros_like(self._eigenvalues)
        # TODO(ikeda): the folling is very bad if we turn on is_star
        self._pr_weights  = np.zeros_like(self._eigenvalues)
        if self._is_eigenvectors or self._use_lapack_solver:
            self._eigenvectors = np.zeros(
                (num_qpoints, num_band, num_band,), dtype='complex128')

        if self._use_lapack_solver:
            print("ERROR: _use_lapack_solver is not considered for this script.")
            raise ValueError
        else:
            for i, q in enumerate(self._qpoints):
                eigvals, eigvecs, self._pr_weights[i], nstar = (
                    self._eigenstates_unfolding.extract_eigenstates(q)
                )
                self._eigenvalues[i] = eigvals.real
                if self._is_eigenvectors:
                    self._eigenvectors[i] = eigvecs
            self._frequencies = np.array(np.sqrt(abs(self._eigenvalues)) *
                                         np.sign(self._eigenvalues),
                                         dtype='double',
                                         order='C') * self._factor
Example #16
0
class Mesh:
    def __init__(
            self,
            dynamical_matrix,
            mesh,
            shift=None,
            is_time_reversal=True,
            is_mesh_symmetry=True,
            is_eigenvectors=False,
            is_gamma_center=False,
            group_velocity=None,
            rotations=None,  # Point group operations in real space
            factor=VaspToTHz):
        self._mesh = np.array(mesh, dtype='intc')
        self._is_eigenvectors = is_eigenvectors
        self._factor = factor
        self._cell = dynamical_matrix.get_primitive()
        self._dynamical_matrix = dynamical_matrix

        self._gp = GridPoints(self._mesh,
                              np.linalg.inv(self._cell.get_cell()),
                              q_mesh_shift=shift,
                              is_gamma_center=is_gamma_center,
                              is_time_reversal=is_time_reversal,
                              rotations=rotations,
                              is_mesh_symmetry=is_mesh_symmetry)
        self._qpoints = self._gp.get_ir_qpoints()
        self._weights = self._gp.get_ir_grid_weights()

        self._frequencies = None
        self._eigenvalues = None
        self._eigenvectors = None
        self._set_phonon()

        self._group_velocities = None
        if group_velocity is not None:
            self._set_group_velocities(group_velocity)

    def get_dynamical_matrix(self):
        return self._dynamical_matrix

    def get_mesh_numbers(self):
        return self._mesh

    def get_qpoints(self):
        return self._qpoints

    def get_weights(self):
        return self._weights

    def get_grid_address(self):
        return self._gp.get_grid_address()

    def get_ir_grid_points(self):
        return self._gp.get_ir_grid_points()

    def get_grid_mapping_table(self):
        return self._gp.get_grid_mapping_table()

    def get_eigenvalues(self):
        return self._eigenvalues

    def get_frequencies(self):
        return self._frequencies

    def get_group_velocities(self):
        return self._group_velocities

    def get_eigenvectors(self):
        """
        Eigenvectors is a numpy array of three dimension.
        The first index runs through q-points.
        In the second and third indices, eigenvectors obtained
        using numpy.linalg.eigh are stored.
        
        The third index corresponds to the eigenvalue's index.
        The second index is for atoms [x1, y1, z1, x2, y2, z2, ...].
        """
        return self._eigenvectors

    def write_yaml(self):
        w = open('mesh.yaml', 'w')
        eigenvalues = self._eigenvalues
        natom = self._cell.get_number_of_atoms()
        lattice = np.linalg.inv(self._cell.get_cell())  # column vectors
        w.write("mesh: [ %5d, %5d, %5d ]\n" % tuple(self._mesh))
        w.write("nqpoint: %-7d\n" % self._qpoints.shape[0])
        w.write("natom:   %-7d\n" % natom)
        w.write("reciprocal_lattice:\n")
        for vec, axis in zip(lattice.T, ('a*', 'b*', 'c*')):
            w.write("- [ %12.8f, %12.8f, %12.8f ] # %2s\n" % (tuple(vec) +
                                                              (axis, )))
        w.write("phonon:\n")

        for i, q in enumerate(self._qpoints):
            w.write("- q-position: [ %12.7f, %12.7f, %12.7f ]\n" % tuple(q))
            w.write("  weight: %-5d\n" % self._weights[i])
            w.write("  band:\n")

            for j, eig in enumerate(eigenvalues[i]):
                w.write("  - # %d\n" % (j + 1))
                if eig < 0:
                    freq = -np.sqrt(-eig)
                else:
                    freq = np.sqrt(eig)
                w.write("    frequency:  %15.10f\n" % (freq * self._factor))

                if self._group_velocities is not None:
                    w.write("    group_velocity: ")
                    w.write("[ %13.7f, %13.7f, %13.7f ]\n" %
                            tuple(self._group_velocities[i, j]))

                if self._is_eigenvectors:
                    w.write("    eigenvector:\n")
                    for k in range(natom):
                        w.write("    - # atom %d\n" % (k + 1))
                        for l in (0, 1, 2):
                            w.write("      - [ %17.14f, %17.14f ]\n" %
                                    (self._eigenvectors[i, k * 3 + l, j].real,
                                     self._eigenvectors[i, k * 3 + l, j].imag))
            w.write("\n")

    def _set_phonon(self):
        num_band = self._cell.get_number_of_atoms() * 3
        num_qpoints = len(self._qpoints)

        self._eigenvalues = np.zeros((num_qpoints, num_band), dtype='double')
        self._frequencies = np.zeros_like(self._eigenvalues)
        if self._is_eigenvectors:
            self._eigenvectors = np.zeros((
                num_qpoints,
                num_band,
                num_band,
            ),
                                          dtype='complex128')

        for i, q in enumerate(self._qpoints):
            self._dynamical_matrix.set_dynamical_matrix(q)
            dm = self._dynamical_matrix.get_dynamical_matrix()
            if self._is_eigenvectors:
                eigvals, self._eigenvectors[i] = np.linalg.eigh(dm)
                self._eigenvalues[i] = eigvals.real
            else:
                self._eigenvalues[i] = np.linalg.eigvalsh(dm).real

        self._frequencies = np.array(
            np.sqrt(abs(self._eigenvalues)) *
            np.sign(self._eigenvalues)) * self._factor

    def _set_group_velocities(self, group_velocity):
        group_velocity.set_q_points(self._qpoints)
        self._group_velocities = group_velocity.get_group_velocity()
Example #17
0
class Mesh:
    def __init__(self,
                 dynamical_matrix,
                 mesh,
                 shift=None,
                 is_time_reversal=True,
                 is_mesh_symmetry=True,
                 is_eigenvectors=False,
                 is_gamma_center=False,
                 group_velocity=None,
                 rotations=None, # Point group operations in real space
                 factor=VaspToTHz):
        self._mesh = np.array(mesh, dtype='intc')
        self._is_eigenvectors = is_eigenvectors
        self._factor = factor
        self._cell = dynamical_matrix.get_primitive()
        self._dynamical_matrix = dynamical_matrix

        self._gp = GridPoints(self._mesh,
                              np.linalg.inv(self._cell.get_cell()),
                              q_mesh_shift=shift,
                              is_gamma_center=is_gamma_center,
                              is_time_reversal=is_time_reversal,
                              rotations=rotations,
                              is_mesh_symmetry=is_mesh_symmetry)
        self._qpoints = self._gp.get_ir_qpoints()
        self._weights = self._gp.get_ir_grid_weights()

        self._frequencies = None
        self._eigenvalues = None
        self._eigenvectors = None
        self._set_phonon()

        self._group_velocities = None
        if group_velocity is not None:
            self._set_group_velocities(group_velocity)

    def get_dynamical_matrix(self):
        return self._dynamical_matrix
        
    def get_mesh_numbers(self):
        return self._mesh
        
    def get_qpoints(self):
        return self._qpoints

    def get_weights(self):
        return self._weights

    def get_grid_address(self):
        return self._gp.get_grid_address()

    def get_ir_grid_points(self):
        return self._gp.get_ir_grid_points()
    
    def get_grid_mapping_table(self):
        return self._gp.get_grid_mapping_table()

    def get_eigenvalues(self):
        return self._eigenvalues

    def get_frequencies(self):
        return self._frequencies

    def get_group_velocities(self):
        return self._group_velocities
    
    def get_eigenvectors(self):
        """
        Eigenvectors is a numpy array of three dimension.
        The first index runs through q-points.
        In the second and third indices, eigenvectors obtained
        using numpy.linalg.eigh are stored.
        
        The third index corresponds to the eigenvalue's index.
        The second index is for atoms [x1, y1, z1, x2, y2, z2, ...].
        """
        return self._eigenvectors


    def write_yaml(self):
        w = open('mesh.yaml', 'w')
        eigenvalues = self._eigenvalues
        natom = self._cell.get_number_of_atoms()
        lattice = np.linalg.inv(self._cell.get_cell()) # column vectors
        w.write("mesh: [ %5d, %5d, %5d ]\n" % tuple(self._mesh))
        w.write("nqpoint: %-7d\n" % self._qpoints.shape[0])
        w.write("natom:   %-7d\n" % natom)
        w.write("reciprocal_lattice:\n")
        for vec, axis in zip(lattice.T, ('a*', 'b*', 'c*')):
            w.write("- [ %12.8f, %12.8f, %12.8f ] # %2s\n" %
                    (tuple(vec) + (axis,)))
        w.write("phonon:\n")

        for i, q in enumerate(self._qpoints):
            w.write("- q-position: [ %12.7f, %12.7f, %12.7f ]\n" % tuple(q))
            w.write("  weight: %-5d\n" % self._weights[i])
            w.write("  band:\n")

            for j, eig in enumerate(eigenvalues[i]):
                w.write("  - # %d\n" % (j+1))
                if eig < 0:
                    freq = -np.sqrt(-eig)
                else:
                    freq = np.sqrt(eig)
                w.write("    frequency:  %15.10f\n" % (freq * self._factor))

                if self._group_velocities is not None:
                    w.write("    group_velocity: ")
                    w.write("[ %13.7f, %13.7f, %13.7f ]\n" %
                            tuple(self._group_velocities[i, j]))

                if self._is_eigenvectors:
                    w.write("    eigenvector:\n")
                    for k in range(natom):
                        w.write("    - # atom %d\n" % (k+1))
                        for l in (0,1,2):
                            w.write("      - [ %17.14f, %17.14f ]\n" %
                                    (self._eigenvectors[i,k*3+l,j].real,
                                     self._eigenvectors[i,k*3+l,j].imag))
            w.write("\n")

    def _set_phonon(self):
        num_band = self._cell.get_number_of_atoms() * 3
        num_qpoints = len(self._qpoints)

        self._eigenvalues = np.zeros((num_qpoints, num_band), dtype='double')
        self._frequencies = np.zeros_like(self._eigenvalues)
        if self._is_eigenvectors:
            self._eigenvectors = np.zeros(
                (num_qpoints, num_band, num_band,), dtype='complex128')
            
        for i, q in enumerate(self._qpoints):
            self._dynamical_matrix.set_dynamical_matrix(q)
            dm = self._dynamical_matrix.get_dynamical_matrix()
            if self._is_eigenvectors:
                eigvals, self._eigenvectors[i] = np.linalg.eigh(dm)
                self._eigenvalues[i] = eigvals.real
            else:
                self._eigenvalues[i] = np.linalg.eigvalsh(dm).real

        self._frequencies = np.array(np.sqrt(abs(self._eigenvalues)) *
                                     np.sign(self._eigenvalues)) * self._factor

    def _set_group_velocities(self, group_velocity):
        group_velocity.set_q_points(self._qpoints)
        self._group_velocities = group_velocity.get_group_velocity()
Example #18
0
class Mesh:
    def __init__(self,
                 dynamical_matrix,
                 cell,
                 mesh,
                 shift=None,
                 is_time_reversal=False,
                 is_mesh_symmetry=True,
                 is_eigenvectors=False,
                 is_band_connection=False,
                 is_gamma_center=False,
                 group_velocity=None,
                 factor=VaspToTHz,
                 symprec=1e-5):
        self._mesh = np.array(mesh)
        self._is_band_connection=is_band_connection
        self._band_order = None
        self._is_eigenvectors = is_eigenvectors
        self._factor = factor
        self._cell = cell
        self._dynamical_matrix = dynamical_matrix
        # self._qpoints, self._weights = get_qpoints(self._mesh,
        #                                            self._cell,
        #                                            shift,
        #                                            is_gamma_center,
        #                                            is_time_reversal,
        #                                            symprec,
        #                                            is_symmetry)
        rotations  = Symmetry(self._cell).get_pointgroup_operations()
        self._gp = GridPoints(self._mesh,
                              np.linalg.inv(self._cell.get_cell()),
                              q_mesh_shift=shift,
                              is_gamma_center=is_gamma_center,
                              is_time_reversal=is_time_reversal,
                              rotations=rotations,
                              is_mesh_symmetry=is_mesh_symmetry)
        self._qpoints = self._gp.get_ir_qpoints()
        self._weights = self._gp.get_ir_grid_weights()

        self._eigenvalues = None
        self._eigenvectors = None
        self._set_eigenvalues()
        if self._is_band_connection:
            self._set_band_connection()

        self._group_velocities = None
        if group_velocity is not None:
            self._set_group_velocities(group_velocity)

    def get_dynamical_matrix(self):
        return self._dynamical_matrix

    def get_mesh_numbers(self):
        return self._mesh

    def get_qpoints(self):
        return self._qpoints

    def get_weights(self):
        return self._weights

    def get_grid_address(self):
        return self._gp.get_grid_address()

    def get_ir_grid_points(self):
        return self._gp.get_ir_grid_points()

    def get_grid_mapping_table(self):
        return self._gp.get_grid_mapping_table()

    def get_eigenvalues(self):
        return self._eigenvalues

    def get_frequencies(self):
        return self._frequencies

    def get_group_velocities(self):
        return self._group_velocities

    def get_eigenvectors(self):
        """
        Eigenvectors is a numpy array of three dimension.
        The first index runs through q-points.
        In the second and third indices, eigenvectors obtained
        using numpy.linalg.eigh are stored.
        
        The third index corresponds to the eigenvalue's index.
        The second index is for atoms [x1, y1, z1, x2, y2, z2, ...].
        """
        return self._eigenvectors

    def write_hdf5(self):
        import h5py
        f=h5py.File('mesh.hdf5', 'w')
        eigenvalues = self._eigenvalues
        natom = self._cell.get_number_of_atoms()
        f.create_dataset('mesh', data=self._mesh)
        f.create_dataset('nqpoint',data=self._qpoints.shape[0])
        f.create_dataset('q-position',data=self._qpoints)
        f.create_dataset('natom',data=natom)
        f.create_dataset('weight', data=self._weights)
        f.create_dataset('frequency',data=self._factor*
                                          np.sign(eigenvalues)*
                                          np.sqrt(np.abs(eigenvalues)))
        if self._group_velocities is not None:
            f.create_dataset('group_velocity', data=self._group_velocities)
        if self._is_eigenvectors:
            f.create_dataset('eigenvector_r',data=self._eigenvectors.real)
            f.create_dataset('eigenvector_i',data=self._eigenvectors.imag)
        if self._is_band_connection:
            f.create_dataset('band_order', data=self._band_order)

    def write_yaml(self):
        f = open('mesh.yaml', 'w')
        eigenvalues = self._eigenvalues
        natom = self._cell.get_number_of_atoms()
        f.write("mesh: [ %5d, %5d, %5d ]\n" % tuple(self._mesh))
        f.write("nqpoint: %-7d\n" % self._qpoints.shape[0])
        f.write("natom:   %-7d\n" % natom)
        f.write("phonon:\n")

        for i, q in enumerate(self._qpoints):
            f.write("- q-position: [ %12.7f, %12.7f, %12.7f ]\n" % tuple(q))
            f.write("  weight: %-5d\n" % self._weights[i])
            f.write("  band:\n")

            for j, eig in enumerate(eigenvalues[i]):
                f.write("  - # %d\n" % (j+1))
                if eig < 0:
                    freq = -np.sqrt(-eig)
                else:
                    freq = np.sqrt(eig)
                f.write("    frequency:  %15.10f\n" % (freq * self._factor))

                if self._group_velocities is not None:
                    f.write("    group_velocity: ")
                    f.write("[ %13.7f, %13.7f, %13.7f ]\n" %
                            tuple(self._group_velocities[i, j]))

                if self._band_order is not None:
                    f.write("    band_order: %-5d\n"%self._band_order[i, j])

                if self._is_eigenvectors:
                    f.write("    eigenvector:\n")
                    for k in range(natom):
                        f.write("    - # atom %d\n" % (k+1))
                        for l in (0,1,2):
                            f.write("      - [ %17.14f, %17.14f ]\n" %
                                    (self._eigenvectors[i,k*3+l,j].real,
                                     self._eigenvectors[i,k*3+l,j].imag))
            f.write("\n")

    def _set_eigenvalues(self):
        eigs = []
        vecs = []
        for q in self._qpoints:
            self._dynamical_matrix.set_dynamical_matrix(q)
            dm = self._dynamical_matrix.get_dynamical_matrix()

            if self._is_eigenvectors:
                val, vec = np.linalg.eigh(dm)
                eigs.append(val.real)
                vecs.append(vec)
            else:
                eigs.append(np.linalg.eigvalsh(dm).real)

        self._eigenvalues = np.array(eigs)
        if self._is_eigenvectors:
            self._eigenvectors = np.array(vecs)

        self._set_frequencies()

    def _set_band_connection(self):
        nband = self._cell.get_number_of_atoms() * 3
        nqpoint = len(self._qpoints)
        qpoints = np.dot(np.linalg.inv(self._cell.get_cell()), self._qpoints.T).T
        band_order = np.zeros((nqpoint, nband), dtype="intc")

        is_degenerate = np.zeros(len(self._eigenvalues), dtype="bool")

        degenerate = []
        for i, freq in  enumerate(self._frequencies):
            deg = get_degenerate_sets(freq, 1e-5)
            degenerate.append(deg)
            if len(deg) != nband:
                is_degenerate[i] = True

        nodegq = qpoints[np.where(is_degenerate == False)]
        indicesn = np.where(is_degenerate == False)[0]
        done = np.zeros(len(indicesn), dtype="bool")
        indicesd = np.where(is_degenerate)[0]
        qpts_dist = np.sum(nodegq ** 2, axis=-1)
        start_q = np.argmin(qpts_dist)
        i=start_q
        band_order[indicesn[start_q]] = np.arange(nband)
        while True:
            done[i]=True
            is_break = True
            for j in np.argsort(np.sum((nodegq-nodegq[i])**2, axis=-1)):
                if not done[j]:
                    is_break = False
                    break
            if is_break:
                break
            for i in np.argsort(np.sum((nodegq-nodegq[j])**2, axis=-1)):
                if done[i]:
                    break
            bi=indicesn[i]
            bj = indicesn[j]
            bo = self._estimate_band_connection(self._qpoints[bi], self._qpoints[bj], band_order[bi])
            band_order[bj] = bo
            i=j
        for id in indicesd:
            j = np.argmin(np.sum((nodegq-qpoints[id])**2, axis=-1))
            ij = indicesn[j]
            if (self._qpoints[id] == np.array([0.48, 0.48, 0])).all():
                self._estimate_band_connection(np.array([0.2, 0.2, 0]), np.array([0.48, 0.48, 0]), np.array([0,1,2,3,4,5]))
            bo = self._estimate_band_connection(self._qpoints[ij],
                                          self._qpoints[id],
                                          band_order[ij])
            band_order[id] = bo
        self._band_order = band_order


    def _estimate_band_connection(self, p, n, band_order_pre):
        self._dynamical_matrix.set_dynamical_matrix(p)
        e1, ev1 = np.linalg.eigh(self._dynamical_matrix.get_dynamical_matrix())
        fre1 = np.array(np.sqrt(abs(e1)) * np.sign(e1)) * self._factor
        self._dynamical_matrix.set_dynamical_matrix(n)
        e2, ev2 = np.linalg.eigh(self._dynamical_matrix.get_dynamical_matrix())
        fre2 = np.array(np.sqrt(abs(e2)) * np.sign(e2)) * self._factor
        deg1 = get_degenerate_sets(fre1, 1e-5)
        deg2 = get_degenerate_sets(fre2, 1e-5)
        assert len(deg1) >= len(deg2)
        mid_point = p + (n-p) * (0.5 +np.random.random() / 10)
        self._dynamical_matrix.set_dynamical_matrix(mid_point)
        evv, evm = np.linalg.eigh(self._dynamical_matrix.get_dynamical_matrix())
        frem = np.array(np.sqrt(abs(evv)) * np.sign(evv)) * self._factor
        degeneratem = get_degenerate_sets(frem, 1e-7)
        assert len(degeneratem) == len(deg1)
        b1 = estimate_band_connection(ev1, evm, band_order_pre, degeneratem, 0.9)
        if b1 is None:
            b1 = self._estimate_band_connection(p, mid_point, band_order_pre)
        b2 = estimate_band_connection(evm, ev2, b1, deg2, 0.9)
        if b2 is not None:
            return b2
        else:
            return self._estimate_band_connection(mid_point, n, b1)


    def _set_frequencies(self):
        ## This expression works only python >= 2.5
        #  frequencies = []
        # for eigs in self._eigenvalues:
        #     frequencies.append(
        #         [np.sqrt(x) if x > 0 else -np.sqrt(-x) for x in eigs])
        
        self._frequencies = np.array(np.sqrt(abs(self._eigenvalues)) *
                                     np.sign(self._eigenvalues)) * self._factor

    def _set_group_velocities(self, group_velocity):
        group_velocity.set_q_points(self._qpoints)
        self._group_velocities = group_velocity.get_group_velocity()
Example #19
0
def test_GridPoints():
    gp = GridPoints([2, 3, 4], [[-1, 1, 1], [1, -1, 1], [1, 1, -1]])
    np.testing.assert_array_equal(gp.grid_address, ga234)
Example #20
0
def test_GridPoints_SnO2_with_rotations_MP(ph_sno2: Phonopy):
    """Test of GridPoints with non-gamma-centre mesh and rotations from SnO2."""
    rec_lat = np.linalg.inv(ph_sno2.primitive.cell)
    rotations = ph_sno2.primitive_symmetry.pointgroup_operations
    gp = GridPoints([4, 4, 4],
                    rec_lat,
                    rotations=rotations,
                    is_gamma_center=False)
    np.testing.assert_array_equal(gp.ir_grid_points, [0, 1, 5, 16, 17, 21])
    np.testing.assert_array_equal(gp.weights, [8, 16, 8, 8, 16, 8])
    np.testing.assert_array_equal(
        gp.grid_mapping_table,
        [
            0,
            1,
            1,
            0,
            1,
            5,
            5,
            1,
            1,
            5,
            5,
            1,
            0,
            1,
            1,
            0,
            16,
            17,
            17,
            16,
            17,
            21,
            21,
            17,
            17,
            21,
            21,
            17,
            16,
            17,
            17,
            16,
            16,
            17,
            17,
            16,
            17,
            21,
            21,
            17,
            17,
            21,
            21,
            17,
            16,
            17,
            17,
            16,
            0,
            1,
            1,
            0,
            1,
            5,
            5,
            1,
            1,
            5,
            5,
            1,
            0,
            1,
            1,
            0,
        ],
    )
    np.testing.assert_allclose(
        gp.qpoints,
        [
            [0.125, 0.125, 0.125],
            [0.375, 0.125, 0.125],
            [0.375, 0.375, 0.125],
            [0.125, 0.125, 0.375],
            [0.375, 0.125, 0.375],
            [0.375, 0.375, 0.375],
        ],
        atol=1e-8,
    )
Example #21
0
class Mesh:
    def __init__(
        self,
        dynamical_matrix,
        mesh,
        shift=None,
        is_time_reversal=True,
        is_mesh_symmetry=True,
        is_eigenvectors=False,
        is_gamma_center=False,
        group_velocity=None,
        rotations=None,  # Point group operations in real space
        factor=VaspToTHz,
        use_lapack_solver=False,
    ):

        self._mesh = np.array(mesh, dtype="intc")
        self._is_eigenvectors = is_eigenvectors
        self._factor = factor
        self._cell = dynamical_matrix.get_primitive()
        self._dynamical_matrix = dynamical_matrix
        self._use_lapack_solver = use_lapack_solver

        self._gp = GridPoints(
            self._mesh,
            np.linalg.inv(self._cell.get_cell()),
            q_mesh_shift=shift,
            is_gamma_center=is_gamma_center,
            is_time_reversal=is_time_reversal,
            rotations=rotations,
            is_mesh_symmetry=is_mesh_symmetry,
        )

        self._qpoints = self._gp.get_ir_qpoints()
        self._weights = self._gp.get_ir_grid_weights()

        self._frequencies = None
        self._eigenvalues = None
        self._eigenvectors = None
        self._set_phonon()

        self._group_velocities = None
        if group_velocity is not None:
            self._set_group_velocities(group_velocity)

    def get_dynamical_matrix(self):
        return self._dynamical_matrix

    def get_mesh_numbers(self):
        return self._mesh

    def get_qpoints(self):
        return self._qpoints

    def get_weights(self):
        return self._weights

    def get_grid_address(self):
        return self._gp.get_grid_address()

    def get_ir_grid_points(self):
        return self._gp.get_ir_grid_points()

    def get_grid_mapping_table(self):
        return self._gp.get_grid_mapping_table()

    def get_eigenvalues(self):
        return self._eigenvalues

    def get_frequencies(self):
        return self._frequencies

    def get_group_velocities(self):
        return self._group_velocities

    def get_eigenvectors(self):
        """
        Eigenvectors is a numpy array of three dimension.
        The first index runs through q-points.
        In the second and third indices, eigenvectors obtained
        using numpy.linalg.eigh are stored.
        
        The third index corresponds to the eigenvalue's index.
        The second index is for atoms [x1, y1, z1, x2, y2, z2, ...].
        """
        return self._eigenvectors

    def write_hdf5(self):
        import h5py

        with h5py.File("mesh.hdf5", "w") as w:
            w.create_dataset("mesh", data=self._mesh)
            w.create_dataset("qpoint", data=self._qpoints)
            w.create_dataset("weight", data=self._weights)
            w.create_dataset("frequency", data=self._frequencies)
            if self._eigenvectors is not None:
                w.create_dataset("eigenvector", data=self._eigenvectors)
            if self._group_velocities is not None:
                w.create_dataset("group_velocity", data=self._group_velocities)

    def write_yaml(self):
        w = open("mesh.yaml", "w")
        eigenvalues = self._eigenvalues
        natom = self._cell.get_number_of_atoms()
        rec_lattice = np.linalg.inv(self._cell.get_cell())  # column vectors
        supercell = self._dynamical_matrix.get_supercell()
        smat = supercell.get_supercell_matrix()
        pmat = self._cell.get_primitive_matrix()
        tmat = np.rint(np.dot(np.linalg.inv(pmat), smat)).astype(int)

        w.write("mesh: [ %5d, %5d, %5d ]\n" % tuple(self._mesh))
        w.write("nqpoint: %-7d\n" % self._qpoints.shape[0])
        w.write("reciprocal_lattice:\n")
        for vec, axis in zip(rec_lattice.T, ("a*", "b*", "c*")):
            w.write("- [ %12.8f, %12.8f, %12.8f ] # %2s\n" % (tuple(vec) + (axis,)))
        w.write("natom:   %-7d\n" % natom)
        w.write(str(PhonopyAtoms(atoms=self._cell)))
        w.write("\n")
        w.write("supercell_matrix:\n")
        for v in tmat:
            w.write("- [ %4d, %4d, %4d ]\n" % tuple(v))

        w.write("\n")
        w.write("phonon:\n")

        for i, q in enumerate(self._qpoints):
            w.write("- q-position: [ %12.7f, %12.7f, %12.7f ]\n" % tuple(q))
            w.write("  weight: %-5d\n" % self._weights[i])
            w.write("  band:\n")

            for j, freq in enumerate(self._frequencies[i]):
                w.write("  - # %d\n" % (j + 1))
                w.write("    frequency:  %15.10f\n" % freq)

                if self._group_velocities is not None:
                    w.write("    group_velocity: ")
                    w.write("[ %13.7f, %13.7f, %13.7f ]\n" % tuple(self._group_velocities[i, j]))

                if self._is_eigenvectors:
                    w.write("    eigenvector:\n")
                    for k in range(natom):
                        w.write("    - # atom %d\n" % (k + 1))
                        for l in (0, 1, 2):
                            w.write(
                                "      - [ %17.14f, %17.14f ]\n"
                                % (self._eigenvectors[i, k * 3 + l, j].real, self._eigenvectors[i, k * 3 + l, j].imag)
                            )
            w.write("\n")

    def _set_phonon(self):
        num_band = self._cell.get_number_of_atoms() * 3
        num_qpoints = len(self._qpoints)

        self._eigenvalues = np.zeros((num_qpoints, num_band), dtype="double")
        self._frequencies = np.zeros_like(self._eigenvalues)
        if self._is_eigenvectors or self._use_lapack_solver:
            self._eigenvectors = np.zeros((num_qpoints, num_band, num_band), dtype="complex128")

        if self._use_lapack_solver:
            from phonopy.phonon.solver import get_phonons_at_qpoints

            get_phonons_at_qpoints(
                self._frequencies,
                self._eigenvectors,
                self._dynamical_matrix,
                self._qpoints,
                self._factor,
                nac_q_direction=None,
                lapack_zheev_uplo="L",
            )
            self._eigenvalues = (
                np.array(self._frequencies ** 2 * np.sign(self._frequencies), dtype="double", order="C")
                / self._factor ** 2
            )
            if not self._is_eigenvectors:
                self._eigenvalues = None
        else:
            for i, q in enumerate(self._qpoints):
                self._dynamical_matrix.set_dynamical_matrix(q)
                dm = self._dynamical_matrix.get_dynamical_matrix()
                if self._is_eigenvectors:
                    eigvals, self._eigenvectors[i] = np.linalg.eigh(dm)
                    self._eigenvalues[i] = eigvals.real
                else:
                    self._eigenvalues[i] = np.linalg.eigvalsh(dm).real
            self._frequencies = (
                np.array(np.sqrt(abs(self._eigenvalues)) * np.sign(self._eigenvalues), dtype="double", order="C")
                * self._factor
            )

    def _set_group_velocities(self, group_velocity):
        group_velocity.set_q_points(self._qpoints)
        self._group_velocities = group_velocity.get_group_velocity()