def __init__(self, cell, symprec=1e-5, is_symmetry=True): self._cell = cell self._symprec = symprec self._symmetry_operations = None self._international_table = None self._dataset = None self._wyckoff_letters = None self._map_atoms = None self._atomic_permutations = None self._pointgroup_operations = None self._pointgroup = None self._independent_atoms = None self._map_operations = None magmom = cell.magnetic_moments if type(magmom) is np.ndarray: if (magmom < symprec).all(): magmom = None if not is_symmetry: self._set_nosym() elif magmom is None: self._set_symmetry_dataset() else: self._set_symmetry_operations_with_magmoms() (self._pointgroup_operations, self._reciprocal_operations) = get_pointgroup_operations( self._symmetry_operations['rotations']) ptg_symbol = spglib.get_pointgroup(self._pointgroup_operations)[0] self._pointgroup = ptg_symbol.strip() self._set_atomic_permutations() self._set_independent_atoms() self._map_operations = self._get_map_operations_from_permutations()
def _get_symmetry_yaml(cell, symmetry, phonopy_version=None): rotations = symmetry.get_symmetry_operations()['rotations'] translations = symmetry.get_symmetry_operations()['translations'] atom_sets = symmetry.get_map_atoms() independent_atoms = symmetry.get_independent_atoms() wyckoffs = symmetry.get_Wyckoff_letters() lines = [] if phonopy_version is not None: lines.append("phonopy_version: '%s'" % phonopy_version) if cell.get_magnetic_moments() is None: spg_symbol, spg_number = symmetry.get_international_table().split() spg_number = int(spg_number.replace('(', '').replace(')', '')) lines.append("space_group_type: '%s'" % spg_symbol) lines.append("space_group_number: %d" % spg_number) lines.append("point_group_type: '%s'" % symmetry.get_pointgroup()) lines.append("space_group_operations:") for i, (r, t) in enumerate(zip(rotations, translations)): lines.append("- rotation: # %d" % (i + 1)) for vec in r: lines.append(" - [%2d, %2d ,%2d]" % tuple(vec)) line = " translation: [" for j, x in enumerate(t): if abs(x - np.rint(x)) < 1e-5: line += " 0.00000" else: line += "%8.5f" % x if j < 2: line += ", " else: line += " ]" lines.append(line) lines.append("atom_mapping:") for i, atom_num in enumerate(atom_sets): lines.append(" %d: %d" % (i + 1, atom_num + 1)) lines.append("site_symmetries:") for i in independent_atoms: sitesym = symmetry.get_site_symmetry(i) lines.append("- atom: %d" % (i + 1)) if cell.get_magnetic_moments() is None: lines.append(" Wyckoff: '%s'" % wyckoffs[i]) site_pointgroup = get_pointgroup(sitesym) lines.append(" site_point_group: '%s'" % site_pointgroup[0].strip()) lines.append(" orientation:") for v in site_pointgroup[2]: lines.append(" - [%2d, %2d, %2d]" % tuple(v)) lines.append(" rotations:") for j, r in enumerate(sitesym): lines.append(" - # %d" % (j + 1)) for vec in r: lines.append(" - [%2d, %2d, %2d]" % tuple(vec)) return "\n".join(lines)
def __init__(self, structure): """ Args: structure: |Structure| object. """ # Get spacegroup from spglib if not available from Abinit. if not structure.has_abi_spacegroup: structure.spgset_abi_spacegroup(has_timerev=True, overwrite=False) self._structure = structure abispg = structure.abi_spacegroup nsym = len(abispg.symrel) indsym = self.structure.indsym #self.eq_atoms = structure.spget_equivalent_atoms() # Precompute sympy objects used to solve linear system of equations. self.sp_symrel, self.sp_symrec = [], [] self.sp_tnons, self.sp_inv_symrel = [], [] from abipy.core.symmetries import mati3inv for symr, symc, tau in zip(abispg.symrel, abispg.symrec, abispg.tnons): self.sp_symrel.append(sp.Matrix((symr))) inv_symr = mati3inv(symr, trans=False) self.sp_inv_symrel.append(sp.Matrix((inv_symr))) self.sp_symrec.append(sp.Matrix((symc))) # FIXME: Should convert to rational numbers # Permissible translations are unit cell translations or fractions thereof # that are consistent with the rotational symmetry (e.g. 1/2, 1/3, 1/4, and 1/6), plus combinations. tau = np.around(tau, decimals=5) self.sp_tnons.append(sp.Matrix(tau)) #from abipy.core.symmetries import indsym_from_symrel #other_indsym = indsym_from_symrel(abispg.symrel, abispg.tnons, self.structure, tolsym=1e-8) #assert np.all(self.structure.indsym == other_indsym) # Compute symmetry operations in Cartesian coordinates (numpy arrays) a = self.structure.lattice.matrix.T self.symcart = np.matmul(a, np.matmul(abispg.symrel, np.linalg.inv(a))) import spglib self.sitesym_labels = [] for iatom, site in enumerate(self.structure): rotations = [ abispg.symrel[isym] for isym in range(nsym) if indsym[iatom, isym, 3] == iatom and abispg.symafm[isym] == 1 ] # Passing a 0-length rotations list to spglib can segfault. herm_symbol, ptg_num = "1", 1 if len(rotations) != 0: herm_symbol, ptg_num, trans_mat = spglib.get_pointgroup( rotations) self.sitesym_labels.append( "%s (#%d,nsym:%d)" % (herm_symbol.strip(), ptg_num, len(rotations)))
def __init__(self, rotations): self._ops = [LatticeRotation(rot) for rot in rotations] # Call spglib to get the Herm symbol. # Remove blanks from C string. herm_symbol, ptg_num, trans_mat = spglib.get_pointgroup(rotations) self.herm_symbol = herm_symbol.strip() #print(self.herm_symbol, ptg_num, trans_mat) if self.sch_symbol is None: raise ValueError("Cannot detect point group symbol! Got sch_symbol = %s" % self.sch_symbol)
def get_point_group(self): """ Get the point group associated with the structure. Returns: (Pointgroup): Point group for structure. """ rotations = self._spacegroup_data["rotations"] # passing a 0-length rotations list to spglib can segfault if len(rotations) == 0: return '1' return spglib.get_pointgroup(rotations)[0].strip()
def get_point_group(self): """ Get the point group associated with the structure. Returns: (Pointgroup): Point group for structure. """ rotations = self._spacegroup_data["rotations"] # passing a 0-length rotations list to spglib can segfault if len(rotations) == 0: return '1' return spglib.get_pointgroup(rotations)[0].strip()
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 get_point_group(atoms, tol=1e-8): """Return the point group operations of a systems.""" rotations, translations = get_symmetry(atoms, tol=tol) point_group = spglib.get_pointgroup(rotations)[0].strip() laue = [ '-1', '2/m', 'mmm', '4/m', '4/mmm', '-3', '-3m', '6/m', '6/mmm', 'm-3', 'm-3m' ] is_laue = point_group in laue return point_group, is_laue
def __init__(self, rotations): rotations = np.reshape(rotations, (-1, 3, 3)) self._ops = [LatticeRotation(rot) for rot in rotations] # Call spglib to get the Herm symbol. # (symbol, pointgroup_number, transformation_matrix) herm_symbol, ptg_num, trans_mat = spglib.get_pointgroup(rotations) # Remove blanks from C string. self.herm_symbol = herm_symbol.strip() #print(self.herm_symbol, ptg_num, trans_mat) if self.sch_symbol is None: raise ValueError("Cannot detect point group symbol! Got sch_symbol = %s" % self.sch_symbol)
def __init__(self, rotations): self._ops = [LatticeRotation(rot) for rot in rotations] # Call spglib to get the Herm symbol. # Remove blanks from C string. import spglib herm_symbol, ptg_num, trans_mat = spglib.get_pointgroup(rotations) self.herm_symbol = herm_symbol.strip() #print(self.herm_symbol, ptg_num, trans_mat) if self.sch_symbol is None: raise ValueError( "Cannot detect point group symbol! Got sch_symbol = %s" % self.sch_symbol)
def _set_grid_matrix_by_input_cell(self, input_cell, length): """Grid generating matrix based on input cell.""" pointgroup = get_pointgroup(self._sym_dataset["rotations"]) # tmat: From input lattice to point group preserving lattice tmat = pointgroup[2] lattice = np.dot(input_cell.cell.T, tmat).T num_cells = np.prod(length2mesh(length, lattice)) self._mesh_numbers = estimate_supercell_matrix_from_pointgroup( pointgroup[1], lattice, num_cells) # transpose in reciprocal space self._grid_matrix = np.array(np.multiply(tmat, self._mesh_numbers).T, dtype="int_", order="C") self._transformation_matrix = np.eye(3, dtype="double", order="C")
def test_standardize_cell_and_pointgroup(self): for fname, spgnum in zip(self._filenames, self._spgnum_ref): cell = read_vasp(fname) if 'distorted' in fname: symprec = 1e-1 else: symprec = 1e-5 std_cell = standardize_cell(cell, to_primitive=False, no_idealize=True, symprec=symprec) dataset = get_symmetry_dataset(std_cell, symprec=symprec) self.assertEqual(dataset['number'], spgnum, msg=("%s" % fname)) # The test for point group has to be done after standarization. ptg_symbol, _, _ = get_pointgroup(dataset['rotations']) self.assertEqual(dataset['pointgroup'], ptg_symbol, msg=("%s" % fname))
def test_standardize_cell_and_pointgroup(self): for fname, spgnum in zip(self._filenames, self._spgnum_ref): cell = read_vasp(fname) if 'distorted' in fname: symprec = 1e-1 else: symprec = 1e-5 std_cell = standardize_cell(cell, to_primitive=False, no_idealize=True, symprec=symprec) dataset = get_symmetry_dataset(std_cell, symprec=symprec) self.assertEqual(dataset['number'], spgnum, msg=("%s" % fname)) # The test for point group has to be done after standarization. ptg_symbol, _, _ = get_pointgroup(dataset['rotations']) self.assertEqual(dataset['pointgroup'], ptg_symbol, msg=("%s" % fname))
def get_pointgroup(structure): """ Get the point group of the crystal structure. Args: structure: :class:`simulation.Structure` object with the crystal structure. Returns: List of point group symbol, point group number, and the transformation matrix. None if `spglib` fails to determine symmetry. Raises: ImportError: If `spglib` cannot be imported. """ _check_spglib_install() data = get_structure_symmetry(structure) if data is None: return None else: return spglib.get_pointgroup(data['rotations'])
def get_pointgroup(self): ro = self.get_symmetry_operations()['rotations'] if len(ro) == 0: return '1' return spglib.get_pointgroup(ro)[0]
print print "[get_spacegroup]" print " Spacegroup of Rutile is ", spglib.get_spacegroup(rutile) print print "[get_spacegroup]" print " Spacegroup of MgB2 is ", spglib.get_spacegroup(MgB2) print print "[get_symmetry]" print " Symmetry operations of Rutile unitcell are:" print symmetry = spglib.get_symmetry(rutile) show_symmetry(symmetry) print print "[get_pointgroup]" print " Pointgroup of Rutile is", spglib.get_pointgroup( symmetry['rotations'])[0] print dataset = spglib.get_symmetry_dataset(rutile) print "[get_symmetry_dataset] ['international']" print " Spacegroup of Rutile is %s (%d) " % (dataset['international'], dataset['number']) print print "[get_symmetry_dataset] ['pointgroup']" print " Pointgroup of Rutile is %s (%d)" % (dataset['pointgroup'], dataset['pointgroup_number']) print print "[get_symmetry_dataset] ['hall']" print " Hall symbol of Rutile is %s (%d)" % (dataset['hall'], dataset['hall_number']) print
print('') print("[get_symmetry]") print(" Symmetry operations of Rutile unitcell are:") print('') symmetry = spglib.get_symmetry(rutile) show_symmetry(symmetry) print('') print("[get_symmetry]") print(" Symmetry operations of MgB2 are:") print('') symmetry = spglib.get_symmetry(MgB2) show_symmetry(symmetry) print('') print("[get_pointgroup]") print(" Pointgroup of Rutile is %s." % spglib.get_pointgroup(symmetry['rotations'])[0]) print('') dataset = spglib.get_symmetry_dataset( rutile ) print("[get_symmetry_dataset] ['international']") print(" Spacegroup of Rutile is %s (%d)." % (dataset['international'], dataset['number'])) print('') print("[get_symmetry_dataset] ['pointgroup']") print(" Pointgroup of Rutile is %s." % (dataset['pointgroup'])) print('') print("[get_symmetry_dataset] ['hall']") print(" Hall symbol of Rutile is %s (%d)." % (dataset['hall'], dataset['hall_number'])) print('') print '========================================================='
def get_rot_trans(myposwan): Amat = myposwan.Amat natom_pos = myposwan.natom_pos atoms_frac = myposwan.atoms_frac atoms_symbol= myposwan.atoms_symbol natom_wan = myposwan.natom_wan atom_num = myposwan.atom_num crystal_ase = Atoms(symbols=atoms_symbol,cell=Amat.T, scaled_positions=atoms_frac.T,pbc=True) symmetry = spglib.get_symmetry(crystal_ase) ptgrp = spglib.get_pointgroup(symmetry['rotations']) nsymm = symmetry['rotations'].shape[0] rotmat = symmetry['rotations'] rottrn = symmetry['translations'] rmat0 = np.array(rotmat[0], dtype = np.float64) # get the number of ptrans nptrans = 0 for i in range(nsymm): rmati = np.array(rotmat[i], dtype = np.float64) diff = abs(rmati-rmat0).sum() #print "i ", i+1, "diff", diff if diff < 1.0E-9: nptrans = nptrans + 1 # get the number of distinct rotaions nrot = nsymm/nptrans print "--------------abstrac of symmetry------------------" print("Spacegroup of this cell is %s." % spglib.get_spacegroup(crystal_ase)) print('Point group: ',ptgrp[0]) print "number of total symmetry operations: ", nsymm print "number of distnct rot ", nrot print "nptrans per rotation", nptrans print "######### For details, see ./mysymmop.dat ########" print "" # check whether rotmat are put as typeI # still need to be tested. err=""" Opps, It seems that in spglib, the rotaions_matrix is not put as ----typeI----- rot1/ptran_11 rot2/ptran_21 ... rotn/ptran_n1 ... ... ... rot1/ptran_1m rot2/ptran_2m ... rotn/ptran_nm If put as above, I want to trans it as in vasp/OUTCAR ----typeII----- rot1/ptran_11 rot1/ptran_12 ... rot1/ptran_1m ... ... ... rotn/ptran_n1 rotn/ptran_n2 ... rotn/ptran_nm """ for isym in range(nrot): rmat0 = np.array(rotmat[isym], dtype = np.float64) diff = 0.0 for iptr in range(nptrans): numb = isym + iptr*nrot rmatt = np.array(rotmat[numb], dtype = np.float64) diff = diff + abs(rmatt-rmat0).sum() if diff>1.0E-5: print err if diff>1.0E-5: sys.exit(0) # To change code less, we use type I and set nptrans=1 nptrans = 1 wann_atom_rotmap=np.zeros((nsymm,nptrans,natom_wan), dtype=np.int32) symop = [] f = open('mysymmop.dat', 'w') for isym in range(nsymm): print>>f, (" --------------- %4d ---------------" % (isym + 1)) rot = symmetry['rotations'][isym] trans = symmetry['translations'][isym] print>>f, (" rotation:") for x in rot: print>>f, (" %2d %2d %2d " % (x[0], x[1], x[2])) print>>f, (" translation:") print>>f, (" %8.5f %8.5f %8.5f " % (trans[0], trans[1], trans[2])) print>>f, (" rotmap:") gtrans = trans ptrans = [np.zeros((3),dtype=np.float64)] # rot map for POSCAR rotmap = [] for iatom in range(natom_pos): atoms_frac_new = np.dot(rotmat[isym],atoms_frac[:,iatom]) + rottrn[isym] # find equiv loc as in original cell for jatom in range(natom_pos): frac_diff = atoms_frac[:,jatom]-atoms_frac_new # determine the equivalent between two atoms before and after space group operation. if abs(frac_diff-np.array([round(i) for i in frac_diff],dtype=np.float64)).sum() < 1.0E-3: print>>f, " ", iatom+1, "->", jatom+1 rotmap.append([iatom+1,jatom+1]) # rot map for wann.in. here for iatom in range(natom_wan): target = rotmap[ atom_num[iatom]-1 ][1] wann_atom_rotmap[isym,0,iatom]=atom_num.index(target) symop.append((rotmat[isym],gtrans,rotmap,ptrans)) print>>f, "\n" print>>f, "\n" print>>f,"rotations as for atoms in wannier projection" # rot map of atoms in wannier projection for isymm in range(nsymm): print >>f, "isymm", isymm+1, "---------" for iptr in range(nptrans): print>>f, "trans", 0, gtrans for ii in range(natom_wan): print>>f, "OUTCAR atom rot map:", atom_num[ii], "->", symop[isymm][2][atom_num[ii]-1][1], "=====>", "wannier atom rot map:", ii+1, "->", wann_atom_rotmap[isymm,iptr,ii]+1 f.close() return nsymm, nptrans, symop, wann_atom_rotmap
print print "[get_spacegroup]" print " Spacegroup of Rutile is ", spglib.get_spacegroup(rutile) print print "[get_spacegroup]" print " Spacegroup of MgB2 is ", spglib.get_spacegroup(MgB2) print print "[get_symmetry]" print " Symmetry operations of Rutile unitcell are:" print symmetry = spglib.get_symmetry( rutile ) show_symmetry(symmetry) print print "[get_pointgroup]" print " Pointgroup of Rutile is", spglib.get_pointgroup(symmetry['rotations'])[0] print dataset = spglib.get_symmetry_dataset( rutile ) print "[get_symmetry_dataset] ['international']" print " Spacegroup of Rutile is %s (%d) " % (dataset['international'], dataset['number']) print print "[get_symmetry_dataset] ['pointgroup']" print " Pointgroup of Rutile is %s (%d)" % (dataset['pointgroup'], dataset['pointgroup_number']) print print "[get_symmetry_dataset] ['hall']" print " Hall symbol of Rutile is %s (%d)" % (dataset['hall'], dataset['hall_number']) print
print('') print("[get_symmetry]") print(" Symmetry operations of Rutile unitcell are:") print('') symmetry = spglib.get_symmetry(rutile) show_symmetry(symmetry) print('') print("[get_symmetry]") print(" Symmetry operations of MgB2 are:") print('') symmetry = spglib.get_symmetry(MgB2) show_symmetry(symmetry) print('') print("[get_pointgroup]") print(" Pointgroup of Rutile is %s." % spglib.get_pointgroup(symmetry['rotations'])[0]) print('') dataset = spglib.get_symmetry_dataset( rutile ) print("[get_symmetry_dataset] ['international']") print(" Spacegroup of Rutile is %s (%d)." % (dataset['international'], dataset['number'])) print('') print("[get_symmetry_dataset] ['pointgroup']") print(" Pointgroup of Rutile is %s." % (dataset['pointgroup'])) print('') print("[get_symmetry_dataset] ['hall']") print(" Hall symbol of Rutile is %s (%d)." % (dataset['hall'], dataset['hall_number'])) print('') print("[get_symmetry_dataset] ['wyckoffs']")
def get_pointgroup(rotations): ptg = spglib.get_pointgroup(rotations) return ptg[0].strip(), ptg[2]