def get_triplets_at_q(grid_point, mesh, point_group, # real space point group of space group primitive_lattice, # column vectors is_time_reversal=True, stores_triplets_map=False): map_triplets, map_q, grid_address = _get_triplets_reciprocal_mesh_at_q( grid_point, mesh, point_group, is_time_reversal=is_time_reversal) bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address, mesh, primitive_lattice) triplets_at_q, weights = _get_BZ_triplets_at_q( grid_point, bz_grid_address, bz_map, map_triplets, mesh) assert np.prod(mesh) == weights.sum(), \ "Num grid points %d, sum of weight %d" % ( np.prod(mesh), weights.sum()) # These maps are required for collision matrix calculation. if not stores_triplets_map: map_triplets = None map_q = None return triplets_at_q, weights, bz_grid_address, bz_map, map_triplets, map_q
def _set_ir_qpoints(self, rotations, is_time_reversal=True): grid_mapping_table, grid_address = get_stabilized_reciprocal_mesh( self._mesh, rotations, is_shift=self._is_shift, is_time_reversal=is_time_reversal) shift = np.array(self._is_shift, dtype='intc') * 0.5 if self._fit_in_BZ: self._grid_address = relocate_BZ_grid_address( grid_address, self._mesh, self._rec_lat, is_shift=self._is_shift)[0][:np.prod(self._mesh)] else: self._grid_address = grid_address (self._ir_grid_points, self._ir_weights) = extract_ir_grid_points(grid_mapping_table) self._ir_qpoints = np.array( (self._grid_address[self._ir_grid_points] + shift) / self._mesh, dtype='double', order='C') self._grid_mapping_table = grid_mapping_table
def _testBrillouinZone(self, direct_lat, mesh, is_shift): _, grid_address = get_stabilized_reciprocal_mesh(mesh, rotations=[ np.eye( 3, dtype='intc'), ], is_shift=is_shift) rec_lat = np.linalg.inv(direct_lat) bz_grid_address, bz_map = relocate_BZ_grid_address(grid_address, mesh, rec_lat, is_shift=is_shift) qpoints = (grid_address + np.array(is_shift) / 2.0) / mesh bz = BrillouinZone(rec_lat) bz.run(qpoints) sv_all = bz.shortest_qpoints # including BZ boundary duplicates sv = [v[0] for v in sv_all] bz_qpoints = (bz_grid_address + np.array(is_shift) / 2.0) / mesh d2_this = (np.dot(sv, rec_lat.T)**2).sum(axis=1) d2_spglib = (np.dot(bz_qpoints[:np.prod(mesh)], rec_lat.T)**2).sum(axis=1) diff = d2_this - d2_spglib diff -= np.rint(diff) # Following both of two tests are necessary. # Check equivalence of vectors by lattice translation np.testing.assert_allclose(diff, 0, atol=1e-8) # Check being in same (hopefull first) Brillouin zone by their lengths np.testing.assert_allclose(d2_this, d2_spglib, atol=1e-8)
def _testBrillouinZone(self, direct_lat, mesh, is_shift): _, grid_address = get_stabilized_reciprocal_mesh( mesh, rotations=[np.eye(3, dtype='intc'), ], is_shift=is_shift) rec_lat = np.linalg.inv(direct_lat) bz_grid_address, bz_map = relocate_BZ_grid_address( grid_address, mesh, rec_lat, is_shift=is_shift) qpoints = (grid_address + np.array(is_shift) / 2.0) / mesh bz = BrillouinZone(rec_lat) bz.run(qpoints) sv_all = bz.shortest_qpoints # including BZ boundary duplicates sv = [v[0] for v in sv_all] bz_qpoints = (bz_grid_address + np.array(is_shift) / 2.0) / mesh d2_this = (np.dot(sv, rec_lat.T) ** 2).sum(axis=1) d2_spglib = (np.dot(bz_qpoints[:np.prod(mesh)], rec_lat.T) ** 2).sum(axis=1) diff = d2_this - d2_spglib diff -= np.rint(diff) # Following both of two tests are necessary. # Check equivalence of vectors by lattice translation np.testing.assert_allclose(diff, 0, atol=1e-8) # Check being in same (hopefull first) Brillouin zone by their lengths np.testing.assert_allclose(d2_this, d2_spglib, atol=1e-8)
def _set_ir_qpoints(self, rotations, is_time_reversal=True): grid_mapping_table, grid_address = get_stabilized_reciprocal_mesh( self._mesh, rotations, is_shift=self._is_shift, is_time_reversal=is_time_reversal) shift = np.array(self._is_shift, dtype='intc') * 0.5 if self._fit_in_BZ: self._grid_address = relocate_BZ_grid_address( grid_address, self._mesh, self._rec_lat, is_shift=self._is_shift)[0][:np.prod(self._mesh)] else: self._grid_address = grid_address (self._ir_grid_points, self._ir_weights) = extract_ir_grid_points(grid_mapping_table) self._ir_qpoints = (self._grid_address[self._ir_grid_points] + shift) / self._mesh self._grid_mapping_table = grid_mapping_table
def get_triplets_at_q( grid_point, mesh, point_group, # real space point group of space group primitive_lattice, # column vectors is_time_reversal=True, stores_triplets_map=False): map_triplets, map_q, grid_address = spg.get_triplets_reciprocal_mesh_at_q( grid_point, mesh, point_group, is_time_reversal=is_time_reversal) bz_grid_address, bz_map = spg.relocate_BZ_grid_address( grid_address, mesh, primitive_lattice) triplets_at_q, weights = spg.get_BZ_triplets_at_q(grid_point, bz_grid_address, bz_map, map_triplets, mesh) assert np.prod(mesh) == weights.sum(), \ "Num grid points %d, sum of weight %d" % ( np.prod(mesh), weights.sum()) # These maps are required for collision matrix calculation. if not stores_triplets_map: map_triplets = None map_q = None return triplets_at_q, weights, bz_grid_address, bz_map, map_triplets, map_q
def get_bz_grid_address(mesh, primitive_lattice, with_boundary=False): grid_address = get_grid_address(mesh) bz_grid_address, bz_map = spg.relocate_BZ_grid_address( grid_address, mesh, primitive_lattice) if with_boundary: return bz_grid_address, bz_map else: return bz_grid_address[:np.prod(mesh)]
def get_bz_grid_address(mesh, primitive_lattice, with_boundary=False): grid_address = get_grid_address(mesh) bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address, mesh, primitive_lattice) if with_boundary: return bz_grid_address, bz_map else: return bz_grid_address[:np.prod(mesh)]
def get_bz_grid_address(mesh, reciprocal_lattice, with_boundary=False): grid_address = get_grid_address(mesh) bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address, mesh, reciprocal_lattice, is_dense=True) if with_boundary: return bz_grid_address, bz_map else: return bz_grid_address[:np.prod(mesh)]
def get_coarse_ir_grid_points(primitive, mesh, mesh_divisors, coarse_mesh_shifts, is_nosym=False, symprec=1e-5): if mesh_divisors is None: mesh_divs = [1, 1, 1] else: mesh_divs = mesh_divisors mesh = np.array(mesh, dtype='intc') mesh_divs = np.array(mesh_divs, dtype='intc') coarse_mesh = mesh / mesh_divs if coarse_mesh_shifts is None: coarse_mesh_shifts = [False, False, False] if is_nosym: coarse_grid_address = get_grid_address(coarse_mesh) coarse_grid_points = np.arange(np.prod(coarse_mesh), dtype='intc') coarse_grid_weights = np.ones(len(coarse_grid_points), dtype='intc') else: symmetry = Symmetry(primitive, symprec) (coarse_grid_points, coarse_grid_weights, coarse_grid_address) = get_ir_grid_points( coarse_mesh, symmetry.get_pointgroup_operations(), mesh_shifts=coarse_mesh_shifts) grid_points = from_coarse_to_dense_grid_points( mesh, mesh_divs, coarse_grid_points, coarse_grid_address, coarse_mesh_shifts=coarse_mesh_shifts) grid_address = get_grid_address(mesh) primitive_lattice = np.linalg.inv(primitive.get_cell()) spg.relocate_BZ_grid_address(grid_address, mesh, primitive_lattice) return grid_points, coarse_grid_weights, grid_address
def get_coarse_ir_grid_points(primitive, mesh, mesh_divisors, coarse_mesh_shifts, is_kappa_star=True, symprec=1e-5): mesh = np.array(mesh, dtype='intc') symmetry = Symmetry(primitive, symprec) point_group = symmetry.get_pointgroup_operations() if mesh_divisors is None: (ir_grid_points, ir_grid_weights, grid_address, grid_mapping_table) = get_ir_grid_points(mesh, point_group) else: mesh_divs = np.array(mesh_divisors, dtype='intc') coarse_mesh = mesh // mesh_divs if coarse_mesh_shifts is None: coarse_mesh_shifts = [False, False, False] if not is_kappa_star: coarse_grid_address = get_grid_address(coarse_mesh) coarse_grid_points = np.arange(np.prod(coarse_mesh), dtype='uintp') else: (coarse_ir_grid_points, coarse_ir_grid_weights, coarse_grid_address, coarse_grid_mapping_table) = get_ir_grid_points( coarse_mesh, point_group, mesh_shifts=coarse_mesh_shifts) ir_grid_points = from_coarse_to_dense_grid_points( mesh, mesh_divs, coarse_grid_points, coarse_grid_address, coarse_mesh_shifts=coarse_mesh_shifts) grid_address = get_grid_address(mesh) ir_grid_weights = ir_grid_weights reciprocal_lattice = np.linalg.inv(primitive.get_cell()) bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address, mesh, reciprocal_lattice, is_dense=True) return (ir_grid_points, ir_grid_weights, bz_grid_address, grid_mapping_table)
def get_coarse_ir_grid_points(primitive, mesh, mesh_divisors, coarse_mesh_shifts, is_kappa_star=True, symprec=1e-5): mesh = np.array(mesh, dtype='intc') symmetry = Symmetry(primitive, symprec) point_group = symmetry.get_pointgroup_operations() if mesh_divisors is None: (ir_grid_points, ir_grid_weights, grid_address, grid_mapping_table) = get_ir_grid_points(mesh, point_group) else: mesh_divs = np.array(mesh_divisors, dtype='intc') coarse_mesh = mesh // mesh_divs if coarse_mesh_shifts is None: coarse_mesh_shifts = [False, False, False] if not is_kappa_star: coarse_grid_address = get_grid_address(coarse_mesh) coarse_grid_points = np.arange(np.prod(coarse_mesh), dtype='intc') coarse_grid_weights = np.ones(len(coarse_grid_points), dtype='intc') else: (coarse_ir_grid_points, coarse_ir_grid_weights, coarse_grid_address, coarse_grid_mapping_table) = get_ir_grid_points( coarse_mesh, point_group, mesh_shifts=coarse_mesh_shifts) ir_grid_points = from_coarse_to_dense_grid_points( mesh, mesh_divs, coarse_grid_points, coarse_grid_address, coarse_mesh_shifts=coarse_mesh_shifts) grid_address = get_grid_address(mesh) ir_grid_weights = ir_grid_weights primitive_lattice = np.linalg.inv(primitive.get_cell()) bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address, mesh, primitive_lattice) return (ir_grid_points, ir_grid_weights, bz_grid_address, grid_mapping_table)
def get_BZ_triplets_at_q(grid_point, mesh, reciprocal_lattice, grid_address, map_q): bz_grid_address, bz_map = spg.relocate_BZ_grid_address( grid_address, mesh, reciprocal_lattice) triplets_at_q, weights = spg.get_BZ_triplets_at_q(grid_point, bz_grid_address, bz_map, map_q, mesh) assert np.prod(mesh) == weights.sum(), \ "Num grid points %d, sum of weight %d" % ( np.prod(mesh), weights.sum()) return triplets_at_q, weights, bz_grid_address, bz_map
def get_bz_grid_address(mesh, primitive_lattice, with_boundary=False, is_bz_map_to_pp=False): "is_bz_map_to_pp: Brillouine zone mapping to the original parallelpipe" grid_address = get_grid_address(mesh) bz_grid_address, bz_map, bz_to_pp_map = spg.relocate_BZ_grid_address(grid_address, mesh, primitive_lattice, is_bz_map_to_orig=is_bz_map_to_pp) if with_boundary: if is_bz_map_to_pp: return bz_grid_address, bz_map, bz_to_pp_map else: return bz_grid_address, bz_map else: return bz_grid_address[:np.prod(mesh)]
def get_nosym_triplets_at_q(grid_point, mesh, primitive_lattice, stores_triplets_map=False): grid_address = get_grid_address(mesh) map_q = np.arange(len(grid_address), dtype='intc') bz_grid_address, bz_map = spg.relocate_BZ_grid_address( grid_address, mesh, primitive_lattice) triplets_at_q, weights = spg.get_BZ_triplets_at_q(grid_point, bz_grid_address, bz_map, map_q, mesh) if not stores_triplets_map: map_q = None return triplets_at_q, weights, bz_grid_address, bz_map, map_q
def get_nosym_triplets_at_q(grid_point, mesh, reciprocal_lattice, stores_triplets_map=False): grid_address = get_grid_address(mesh) map_triplets = np.arange(len(grid_address), dtype='intc') bz_grid_address, bz_map = spg.relocate_BZ_grid_address( grid_address, mesh, reciprocal_lattice) triplets_at_q, weights = _get_BZ_triplets_at_q(grid_point, bz_grid_address, bz_map, map_triplets, mesh) if not stores_triplets_map: map_triplets = None map_q = None else: map_q = map_triplets.copy() return triplets_at_q, weights, bz_grid_address, bz_map, map_triplets, map_q
def get_bz_grid_address(mesh, primitive_lattice, with_boundary=False, is_bz_map_to_pp=False): "is_bz_map_to_pp: Brillouine zone mapping to the original parallelpipe" grid_address = get_grid_address(mesh) bz_grid_address, bz_map, bz_to_pp_map = spg.relocate_BZ_grid_address( grid_address, mesh, primitive_lattice, is_bz_map_to_orig=is_bz_map_to_pp) if with_boundary: if is_bz_map_to_pp: return bz_grid_address, bz_map, bz_to_pp_map else: return bz_grid_address, bz_map else: return bz_grid_address[:np.prod(mesh)]
def get_BZ_triplets_at_q(grid_point, mesh, reciprocal_lattice, grid_address, map_q): bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address, mesh, reciprocal_lattice) triplets_at_q, weights = spg.get_BZ_triplets_at_q( grid_point, bz_grid_address, bz_map, map_q, mesh) assert np.prod(mesh) == weights.sum(), \ "Num grid points %d, sum of weight %d" % ( np.prod(mesh), weights.sum()) return triplets_at_q, weights, bz_grid_address, bz_map
def get_nosym_triplets_at_q(grid_point, mesh, primitive_lattice, stores_triplets_map=False): grid_address = get_grid_address(mesh) map_q = np.arange(len(grid_address), dtype='intc') bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address, mesh, primitive_lattice) triplets_at_q, weights = spg.get_BZ_triplets_at_q( grid_point, bz_grid_address, bz_map, map_q, mesh) if not stores_triplets_map: map_q = None return triplets_at_q, weights, bz_grid_address, bz_map, map_q
from phonopy.structure.spglib import get_ir_reciprocal_mesh, relocate_BZ_grid_address import sys cell = read_vasp(sys.argv[1]) symmetry = Symmetry(cell) mesh = [4, 4, 4] is_shift = np.array([0, 0, 0], dtype='intc') mapping_table, grid_address = get_ir_reciprocal_mesh( mesh, cell, is_shift=is_shift) ir_grid_points = np.unique(mapping_table) primitive_vectors = np.linalg.inv(cell.get_cell()) bz_grid_address, bz_map = relocate_BZ_grid_address( grid_address, mesh, np.linalg.inv(cell.get_cell()), is_shift=is_shift) bz_points = np.extract(bz_map > -1, bz_map) qpoints = (grid_address + is_shift / 2.0) / mesh qpoints -= (qpoints > 0.5001) * 1 bz = BrillouinZone(primitive_vectors) bz.run(qpoints) sv = bz.get_shortest_qpoints() print("%d %d" % (len(bz_points), np.sum(len(x) for x in sv))) for q, vs in zip(qpoints, sv): if np.allclose(q, vs[0]): print(q) else:
def _set_grid_address(self): grid_address = get_grid_address(self._mesh) self._grid_address, self._bz_map = spg.relocate_BZ_grid_address( grid_address, self._mesh, np.linalg.inv(self._primitive.get_cell()))
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 get_triplets_at_q(grid_point, mesh, point_group, # real space point group of space group reciprocal_lattice, # column vectors is_time_reversal=True, swappable=True, stores_triplets_map=False): """Parameters ---------- grid_point : int A grid point mesh : array_like Mesh numbers shape=(3,), dtype='intc' point_group : array_like Rotation matrices in real space. Note that those in reciprocal space mean these matrices transposed (local terminology). shape=(n_rot, 3, 3), dtype='intc', order='C' reciprocal_lattice : array_like Reciprocal primitive basis vectors given as column vectors shape=(3, 3), dtype='double', order='C' is_time_reversal : bool, optional Inversion symemtry is added if it doesn't exist. Default is True. swappable : bool, optional q1 and q2 among (q0, q1, q2) can be swapped. Deafult is True. Returns ------- triplets_at_q : ndarray Symmetry reduced number of triplets are stored as grid point integer numbers. shape=(n_triplets, 3), dtype='uintp' weights : ndarray Weights of triplets in Brillouin zone shape=(n_triplets,), dtype='intc' bz_grid_address : ndarray Integer grid address of the points in Brillouin zone including surface. The first prod(mesh) numbers of points are independent. But the rest of points are translational-symmetrically equivalent to some other points. shape=(n_grid_points, 3), dtype='intc', order='C' bz_map : ndarray Grid point mapping table containing BZ surface. See more detail in spglib docstring. shape=(prod(mesh*2),), dtype='uintp' map_tripelts : ndarray or None Returns when stores_triplets_map=True, otherwise None is returned. Mapping table of all triplets to symmetrically independent tripelts. More precisely, this gives a list of index mapping from all q-points to independent q' of q+q'+q''=G. Considering q' is enough because q is fixed and q''=G-q-q' where G is automatically determined to choose smallest |G|. shape=(prod(mesh),), dtype='uintp' map_q : ndarray or None Returns when stores_triplets_map=True, otherwise None is returned. Irreducible q-points stabilized by q-point of specified grid_point. shape=(prod(mesh),), dtype='uintp' """ map_triplets, map_q, grid_address = _get_triplets_reciprocal_mesh_at_q( grid_point, mesh, point_group, is_time_reversal=is_time_reversal, swappable=swappable) bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address, mesh, reciprocal_lattice, is_dense=True) triplets_at_q, weights = _get_BZ_triplets_at_q( grid_point, bz_grid_address, bz_map, map_triplets, mesh) assert np.prod(mesh) == weights.sum(), \ "Num grid points %d, sum of weight %d" % ( np.prod(mesh), weights.sum()) # These maps are required for collision matrix calculation. if not stores_triplets_map: map_triplets = None map_q = None return triplets_at_q, weights, bz_grid_address, bz_map, map_triplets, map_q