def get_reduced_bases(lattice, method='niggli', tolerance=1e-5): """Search kinds of shortest basis vectors Parameters ---------- lattice : ndarray or list of list Basis vectors by row vectors, [a, b, c]^T shape=(3, 3) method : str delaunay: Delaunay reduction niggli: Niggli reduction tolerance : float Tolerance to find shortest basis vecotrs Returns -------- Reduced basis as row vectors, [a_red, b_red, c_red]^T dtype='double' shape=(3, 3) order='C' """ if method == 'niggli': return spglib.niggli_reduce(lattice, eps=tolerance) else: return spglib.delaunay_reduce(lattice, eps=tolerance)
def reduce(struct): """ Compute reduced lattice of the input Structure. This will modify input structure. """ lv = struct.get_lattice_vectors() rcell = niggli_reduce(lv) struct.reset_lattice_vectors(list(rcell)) return struct
def spginfo(self): cell = (self.a, self.frac, self.charges) print("[get_spacegroup]") print(" Spacegroup of cell is %s" % spg.get_spacegroup(cell)) print("[get_symmetry]") print(" Symmetry operations of unitcell are") symmetry = spg.get_symmetry(cell) show_symmetry(symmetry) print("[get_pointgroup]") print(" Pointgroup of cell is %s" % spg.get_pointgroup(symmetry['rotations'])[0]) dataset = spg.get_symmetry_dataset(cell) print("[get_symmetry_dataset] ['international']") print(" Spacegroup of cell is %s (%d)" % (dataset['international'], dataset['number'])) print("[get_symmetry_dataset] ['pointgroup']") print(" Pointgroup of cell is %s" % (dataset['pointgroup'])) print("[get_symmetry_dataset] ['hall']") print(" Hall symbol of cell is %s (%d)." % (dataset['hall'], dataset['hall_number'])) print("[get_symmetry_dataset] ['wyckoffs']") alphabet = "abcdefghijklmnopqrstuvwxyz" print(" Wyckoff letters of cell are ", dataset['wyckoffs']) print("[get_symmetry_dataset] ['equivalent_atoms']") print(" Mapping to equivalent atoms of cell ") for i, x in enumerate(dataset['equivalent_atoms']): print(" %d -> %d" % (i + 1, x + 1)) print("[get_symmetry_dataset] ['rotations'], ['translations']") print(" Symmetry operations of unitcell are:") for i, (rot, trans) in enumerate( zip(dataset['rotations'], dataset['translations'])): print(" --------------- %4d ---------------" % (i + 1)) print(" rotation:") for x in rot: print(" [%2d %2d %2d]" % (x[0], x[1], x[2])) print(" translation:") print(" (%8.5f %8.5f %8.5f)" % (trans[0], trans[1], trans[2])) reduced_lattice = spg.niggli_reduce(self.a) print("[niggli_reduce]") print(" Original lattice") show_lattice(self.a) print(" Reduced lattice") show_lattice(reduced_lattice) mapping, grid = spg.get_ir_reciprocal_mesh([11, 11, 11], cell, is_shift=[0, 0, 0]) num_ir_kpt = len(numpy.unique(mapping)) print("[get_ir_reciprocal_mesh]") print(" Number of irreducible k-points of primitive") print(" 11x11x11 Monkhorst-Pack mesh is %d " % num_ir_kpt) return self
def niggliReduce(self, eps=1e-5): """ Niggli reduction Arguments: eps: tolerance parameter, but unlike symprec the unit is not a length. This is used to check if difference of norms of two basis vectors is close to zero or not and if two basis vectors are orthogonal by the value of dot product being close to zero or not. The detail is shown at https://atztogo.github.io/niggli/. """ cell = self.structure.formatting('cell') lattice = cell['lattice'] niggli_lattice = spglib.niggli_reduce(lattice, eps=eps) return niggli_lattice
symmetry = spglib.get_symmetry(silicon) print("[get_symmetry]") print(" Number of symmetry operations of silicon conventional") print(" unit cell is %d (192)." % len(symmetry['rotations'])) show_symmetry(symmetry) print('') symmetry = spglib.get_symmetry_from_database(525) print("[get_symmetry_from_database]") print(" Number of symmetry operations of silicon conventional") print(" unit cell is %d (192)." % len(symmetry['rotations'])) show_symmetry(symmetry) print('') reduced_lattice = spglib.niggli_reduce(niggli_lattice) print("[niggli_reduce]") print(" Original lattice") show_lattice(niggli_lattice) print(" Reduced lattice") show_lattice(reduced_lattice) print('') mapping, grid = spglib.get_ir_reciprocal_mesh([11, 11, 11], silicon_prim, is_shift=[0, 0, 0]) num_ir_kpt = len(np.unique(mapping)) print("[get_ir_reciprocal_mesh]") print(" Number of irreducible k-points of primitive silicon with") print(" 11x11x11 Monkhorst-Pack mesh is %d (56)." % num_ir_kpt)
def get_HSKP(self, structure): structure_dataset = spglib.get_symmetry_dataset(structure, symprec = 1e-05, angle_tolerance = -1.0) structure_basis = structure_dataset['std_lattice'] sgnum = structure_dataset['number'] hall_num = structure_dataset['hall_number'] pg_international = spglib.get_spacegroup_type(hall_num)['pointgroup_international'] inversion_symmetry = self.pg_inversion(self.get_pgnum(pg_international)) a, b, c, cosalpha, cosbeta, cosgamma = self.get_lattice_constant(structure_basis) time_reversal = True if sgnum in range (195, 231): self.cubic(sgnum) elif sgnum in range (75, 143): self.tetragonal(sgnum, a, b, c) elif sgnum in range (16, 75): self.orthorhombic(sgnum, a, b, c) elif sgnum in range (168, 195): self.hexagonal(sgnum) elif sgnum in range (143, 168): self.trigonal(sgnum, a, b, c) elif sgnum in range(3, 16): self.monoclinic(sgnum, a, b, c, cosbeta) elif sgnum in (1, 3): rec1 = self.rec_real_transf(structure_basis) rec2 = spglib.niggli_reduce(rec1) real2 = self.rec_real_transf(rec2) ka2, kb2, kc2, coskalpha2, coskbeta2, coskgamma2 = self.get_lattice_constant(rec2) conditions = np.array([abs(kb2 * kc2 * coskalpha2), \ abs(kc2 * ka2 * coskbeta2), \ abs(ka2 * kb2 * coskgamma2)]) matrix_M2 = [np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]]), \ np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]), \ np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])] smallest_condition = np.argsort(conditions)[0] M2 = matrix_M2[smallest_condition] real3 = np.dot(np.array(real2).T, M2).T rec3 = self.rec_real_transf(real3) ka3, kb3, kc3, coskalpha3, coskbeta3, coskgamma3 = self.get_lattice_constant(rec3) if (coskalpha3 > 0. and coskbeta3 > 0 and coskgamma3 > 0) or \ (coskalpha3 < 0 and coskbeta3 < 0 and coskgamma3 < 0): matrix_M3 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) elif (coskalpha3 > 0 and coskbeta3 < 0 and coskgamma3 < 0) or \ (coskalpha3 < 0 and coskbeta3 > 0 and coskgamma3 > 0): matrix_M3 = np.array([[1, 0, 0], [0, -1, 0], [0, 0, -1]]) elif (coskalpha3 < 0 and coskbeta3 > 0 and coskgamma3 < 0) or \ (coskalpha3 > 0 and coskbeta3 < 0 and coskgamma3 > 0): matrix_M3 = np.array([[-1, 0, 0], [0, 1, 0], [0, 0, -1]]) elif (coskalpha3 < 0 and coskbeta3 < 0 and coskgamma3 > 0) or \ (coskalpha3 > 0 and coskbeta3 > 0 and coskgamma3 < 0): matrix_M3 = np.array([[-1, 0, 0], [0, -1, 0], [0, 0, 1]]) else: print('Error! Can not get M3 matrix for aP lattice') real4 = np.dot(real3.T, matrix_M3).T rec4 = self.rec_real_transf(real4) ka, kb, kc, coskalpha, coskbeta, coskgamma = get_cell_params(rec4) self.triclinic(coskalpha, coskbeta, coskgamma) if not inversion_symmetry and not time_reversal: augmented_path = True else: augmented_path = False if augmented_path: for pointname, coords in list(self.kpath['Kpoints'].items()): if pointname == '\Gamma': continue self.kpath['Kpoints']["{}'".format(pointname)] = \ [-coords[0], -coords[1], -coords[2]] for i in range(0, len(self.kpath['Path'])): path_list = [] old_path = copy.deepcopy(self.kpath['Path'][i - 1]) for path in old_path: if path == '\Gamma': new_path = path else: new_path = "{}'".format(path) path_list.append(new_path) self.kpath['Path'].append(path_list)