def get_irrep(self, group_data: List[SymmOp], stokes_number: int, dimension: int, k_params=(None, None, None)): """ Args: stokes_number: Unique number of the irrep as defined by ISO-IR (Stoked et al.) dimension: Dimension of the irrep k_params: Arbitrary for high symmetry k-point lookup group_data: List of matrix vector pairs in the symmetry group as instances of SymmOp Returns: An instance of Irrep containing all matrix and irrep information """ if not all([isinstance(i, SymmOp) for i in group_data]): raise ValueError( "Matrix-vector pairs in group data must be instances of SymmOp." ) irrep_matrices = [] for op in group_data: mult = 1.0 tvec = op.translation_vector while (any( np.logical_and((mult * tvec) % 1.0 > 0.05, (mult * tvec) % 1.0 < 0.95))): mult += 1.0 std_mat = op.affine_matrix * mult std_trans = mult * op.translation_vector std_mat[0:3, 3] = np.rint(std_trans) std_mat = SymmOp(std_mat.astype(int)) irrep_matrices.append( self.get_irrep_mat(stokes_number=stokes_number, dimension=dimension, k_params=k_params, symmop=std_mat)) return Irrep(irrep_matrices=irrep_matrices, group_data=group_data, label=irrep_matrices[0].label, stokes_number=stokes_number, dimension=dimension)
def get_symops_from_OUTCAR(outfile): """ add s1 operator also if it doesn't exist """ with open(outfile,'r') as f: data=f.read().split('\n') start_line=0 end_line=0 for line_num,line in enumerate(data): if 'Space group operators:' in line: start_line = line_num end_line = 0 elif start_line and not end_line and not len(line.split()): end_line = line_num ops=[] for line_num in range(start_line+2,end_line): cont=data[line_num].split() op={} op['det']=int(float(cont[1])) op['angle']=float(cont[2]) op['axis']=[float(cont[3]),float(cont[4]),float(cont[5])] ops.append(op) ops_matrix=[] s1=np.array([[-1,0,0],[0,-1,0],[0,0,-1]]) mats=[] for op in ops: mat=get_rotation_matrix_from_axis_angle(op['axis'],op['angle'],op['det']) mat1=np.round(np.array(mat),3) mats.append(mat1) exist = False for mat in mats: if not (mat-s1).any(): exist = True break for mat in mats: op1=SymmOp.from_rotation_and_translation(mat,[0,0,0]) ops_matrix.append(op1) if exist: continue mat2=np.dot(s1,mat) op2=SymmOp.from_rotation_and_translation(mat2,[0,0,0]) ops_matrix.append(op2) return ops_matrix
def test_get_irrep_mat(): stokes_number = 7611 dimension = 3 symmop = SymmOp([[0, 3, 0, -1], [-3, 3, 0, 1], [0, 0, -3, 1], [0, 0, 0, 3]]) irr = IrrepTools() irrep_mat = irr.get_irrep_mat(stokes_number=stokes_number, dimension=dimension, symmop=symmop) assert irrep_mat.matrix.tolist() == [[0, 0, -1], [-1, 0, 0], [0, 1, 0]] assert irrep_mat.label == "F1+"
def test_get_irrep_mat(self): stokes_number = 7611 dimension = 3 symmop = SymmOp([[0, 3, 0, -1], [-3, 3, 0, 1], [0, 0, -3, 1], [0, 0, 0, 3]]) irr = IrrepTools() irrep_mat = irr.get_irrep_mat( stokes_number=stokes_number, dimension=dimension, symmop=symmop) self.assertEqual(irrep_mat.matrix.tolist(), [ [0, 0, -1], [-1, 0, 0], [0, 1, 0]]) self.assertEqual(irrep_mat.label, 'F1+')
def sg_pg_compare(mpid='mp-989535'): stru = m.get_structure_by_material_id(mpid) spa = SpacegroupAnalyzer(stru) pg_name = spa.get_symmetry_dataset()['pointgroup'] pg_ops = PointGroup(pg_name).symmetry_ops sp_ops = [] sp_mats = [] pg_mats = [] for op in pg_ops: rotation = op.rotation_matrix pg_mats.append(jsanitize(rotation)) for op in spa.get_symmetry_operations(): rotation = op.rotation_matrix sp_mats.append(jsanitize(rotation)) sp_ops.append(SymmOp.from_rotation_and_translation( rotation, (0, 0, 0))) sp_ops = set(sp_ops) #pg_mats.sort();sp_mats.sort() return pg_mats, sp_mats
def standardize(self, images, vectol, symprec, tmat, oshift): DG_std = [] DG = self.matrices for i in range(len(DG)): std_mat = np.dot( np.dot(tmat, DG[i].rotation_matrix), np.linalg.inv(tmat)) std_trans = np.dot(tmat, DG[i].translation_vector) + oshift - \ np.dot( np.dot(np.dot(tmat, DG[i].rotation_matrix), np.linalg.inv(tmat)), oshift) DG_std.append( SymmOp.from_rotation_and_translation(std_mat, std_trans)) self.std_matrices = DG_std self.trans_mat = tmat self.oshift = oshift
def from_images( cls, images: List, symprec: float, angle_tolerance: float, gentol: float, vectol: List[float], vectol2: List[float], ): dataset = cls.get_img_sym_data(images, symprec, angle_tolerance, gentol) # -- Finds H, the symmetry operations common for each image # H[0] is the list of rotations, H[1] is the list of translations numIm = len(images) H = [[], []] # type: List[List] rotH = dataset[0]["rotations"] tranH = dataset[0]["translations"] for i in range(0, len(rotH)): add = True for data in dataset: found = False for j in range(0, len(data["rotations"])): if np.allclose( data["rotations"][j], rotH[i], atol=gentol, rtol=0.0) and closewrapped( data["translations"][j], tranH[i], vectol2): found = True break if not found: add = False break if add: H[0].append(rotH[i]) H[1].append(tranH[i]) # -- Finds A*, the starred symmetry operations that map all images to their opposite image # Astar[0] is the list of rotations, Astar[1] is the list of translations Astar = [[], []] # type: List[List] rotA = dataset[int(numIm / 2)]["rotations"] tranA = dataset[int(numIm / 2)]["translations"] for i in range(0, len(rotA)): add = True for j in range(0, int(numIm / 2)): positions = images[j].frac_coords positions = np.dot(positions, np.transpose(rotA[i])) positions = positions + findtranslation( images[int(numIm / 2)], rotA[i], tranA[i], gentol, vectol2, symprec, angle_tolerance) newimage = images[j].copy() new_species = newimage.species for k in range(len(new_species)): newimage.replace(k, new_species[k], positions[k]) if not atomsequal(newimage, images[numIm - 1 - j], vectol): add = False break if add: Astar[0].append(rotA[i]) Astar[1].append(tranA[i]) # -- Finds the general distortion group with a direct product of H and A* # DG[0] is the list of rotations, DG[1] is the list of translations # The first len(H[0]) operations are unstarred operations; the rest are starred. DG = [] for i in range(0, len(H[0])): DG.append(SymmOp.from_rotation_and_translation(H[0][i], H[1][i])) for i in range(0, len(H[0])): for j in range(0, len(Astar[0])): add = True testrot = np.dot(H[0][i], Astar[0][j]) testtran = standardize( np.dot(Astar[1][j], np.transpose(H[0][i])) + H[1][i], gentol) for k in range(len(H[0]), len(DG)): if np.allclose(testrot, DG[k].rotation_matrix, atol=gentol) and closewrapped( testtran, DG[k].translation_vector, vectol): add = False break if add: DG.append( SymmOp.from_rotation_and_translation( testrot, testtran)) return cls(matrices=DG, num_unstar=len(H[0]), img_sym_dataset=dataset)
def test_get_irrep(self): stokes_number = 2857 dimension = 1 matrices = [[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]], [[-1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], [[1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]], [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]], [[-1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], [[1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]], [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]], [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, -1.0]], [[1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]], [[-1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, -1.0]], [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]], [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, -1.0]], [[1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]], [[-1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, -1.0]]] vectors = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.5], [1.0, 0.0, 0.0], [0.0, 0.0, 0.5], [0.5, -0.5, 0.0], [1.4999999959999997, -0.4999999999999998, 0.5], [1.4999999959999997, -0.5, 0.0], [0.5, -0.4999999999999998, 0.5], [1.0, 0.0, 0.0], [0.0, 0.0, 0.4999868850768938], [0.0, 0.0, 0.0], [1.0, 0.0, 0.4999868850768938], [1.4999998980000022, -0.5, 0.0], [0.5, -0.5, 0.4999868850768938], [0.5, -0.5, 0.0], [1.4999998980000022, -0.5, 0.4999868850768938]] group_data = [] for entry in range(len(matrices)): group_data.append(SymmOp.from_rotation_and_translation(rotation_matrix=matrices[entry], translation_vec=vectors[entry])) ir_mat_data = [[[1]], [[-1]], [[-1]], [[1]], [[-1]], [[1]], [[1]], [[-1]], [[1]], [[-1]], [[-1]], [[1]], [[-1]], [[1]], [[1]], [[-1]]] irr = IrrepTools() irrep = irr.get_irrep(group_data=group_data, stokes_number=stokes_number, dimension=dimension, k_params=(None, None, None)) irmats = irrep.irrep_matrices for op_num in range(len(irmats)): self.assertEqual(irmats[op_num].matrix, ir_mat_data[op_num]) self.assertEqual(irrep.label, 'Y4+')