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
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
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
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)
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
def _run_py_tetrahedron_method(self, is_band_freq=False): 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.set_phonons(self._vertices.ravel()) if is_band_freq: self._frequency_points = self._frequencies[self._grid_point] else: 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[:, 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)
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)
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)
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)