def get_irrep_matrices(path, io): DG_std = path.distortion_group.std_matrices io.print("\n\nIrrep. #" + str(io.irr_num) + " chosen...") if io.irr_num != 0: irrep_tools = IrrepTools() irrep = irrep_tools.get_irrep(group_data=DG_std, stokes_number=io.irr_num, dimension=io.irr_dim, k_params=(None, None, None)) else: raise ValueError("No irrep chosen.") io.print("\n\n") io.print("------- Irrep. Matrices:\n") for j in range(0, len(irrep)): irrep_matrix = irrep.irrep_matrices[j].matrix io.print("Symmetry Element " + str(j + 1) + " : \n" + str(irrep_matrix) + "\n") return irrep
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 get_irrep_matrices(path, io): DG_std = path.distortion_group.std_matrices if io.irr_num != 0: irrep_tools = IrrepTools() irrep = irrep_tools.get_irrep(group_data=DG_std, stokes_number=io.irr_num, dimension=io.irr_dim, k_params=(None, None, None)) else: raise ValueError("No irrep chosen.") return irrep
def print_irreps(iso_sg_name,io): io.print ("\n-------\n------- Possible irreps of the distortion group:\n-------\n") out_text = IrrepTools.possible_irreps(iso_sg_name) io.print(out_text)
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+')
def gen_perturb(path, irrep, io): images = path.images DG = path.distortion_group.matrices num_unstar = path.distortion_group.num_unstar numIm = len(images) irrep_tools = IrrepTools() # -- Generate starting basis atoms1 = images[0].frac_coords numAtoms = len(atoms1) basis = np.zeros(numAtoms) atoms2 = images[numIm - 1].frac_coords m_vec = np.dot(np.linalg.inv(images[0].lattice.matrix), [io.min_move, io.min_move, io.min_move]) for i in range(0, numAtoms): if not closewrapped(atoms1[i, :], atoms2[i, :], m_vec): basis[i] = 1 # -- Generate matrix showing atom mapping for each operations a_map = path.gen_atom_map(basis=basis, vectol=io.vectol) # -- Generate and apply modes for an irrep of arbitrary dimension pt = np.zeros((numIm, numAtoms, 3)) pt_mode_init = irrep_tools.projection_diag(images=images, symmop_list=DG, irrep=irrep, num_unstar=num_unstar, a_map=a_map, basis=basis) if not np.any(pt_mode_init): raise RuntimeError( f"Uniform random initial perturbation does not contain any non-zero contributions from irrep {irrep.stokes_number}.\ Try a different irrep.") pt_mode_init = pt_mode_init / np.linalg.norm( np.ndarray.flatten(pt_mode_init)) pt += io.m_co[0] * pt_mode_init if io.irr_dim > 1: for i in range(1, io.irr_dim): pt_mode = irrep_tools.projection_odiag( images=images, symmop_list=DG, num_unstar=num_unstar, irrep=irrep, vec=pt_mode_init, index=i, a_map=a_map, basis=basis, ) pt += io.m_co[i] * (pt_mode / np.linalg.norm(np.ndarray.flatten(pt_mode))) p_vec = [ io.p_mag / np.linalg.norm(images[0].lattice.matrix[m, :]) for m in range(0, 3) ] # print pt[3]/np.amax(abs(pt[3])) # print(np.amax(p_vec*(pt[:,:,:]/np.amax(abs(pt))))) images_alt = [] for i in range(numIm): image_copy = images[i].copy() alt_species = image_copy.species perturbed_coords = image_copy.frac_coords + p_vec * (pt[i, :, :] / np.amax(abs(pt))) for j in range(numAtoms): image_copy.replace(j, alt_species[j], perturbed_coords[j]) images_alt.append(image_copy) return images_alt, basis
def gen_perturb(path, irrep, io): images = path.images DG = path.distortion_group.matrices num_unstar = path.distortion_group.num_unstar numIm = len(images) irrep_tools = IrrepTools() io.print("\n\n\n\n" + ("=" * 27 + "\n") * 2 + "\nGenerating perturbations...\n\n" + ("=" * 27 + "\n") * 2 + "\n") io.print("***THE FOLLOWING DATA IS FOR THE PERTURBED IMAGES***\n\n") # -- Generate starting basis atoms1 = images[0].frac_coords numAtoms = len(atoms1) basis = np.zeros(numAtoms) atoms2 = images[numIm - 1].frac_coords m_vec = np.dot(np.linalg.inv(images[0].lattice.matrix), [io.min_move, io.min_move, io.min_move]) for i in range(0, numAtoms): if not closewrapped(atoms1[i, :], atoms2[i, :], m_vec): basis[i] = 1 io.print("------- Atoms included in basis:") symbols = images[0].species for i in range(0, numAtoms): if basis[i] == 0: io.print(str(symbols[i]) + " No") else: io.print(str(symbols[i]) + " Yes") # -- Generate matrix showing atom mapping for each operations a_map = path.gen_atom_map(basis=basis, vectol=io.vectol) # -- Generate and apply modes for an irrep of arbitrary dimension pt = np.zeros((numIm, numAtoms, 3)) pt_mode_init = irrep_tools.projection_diag(images=images, symmop_list=DG, irrep=irrep, num_unstar=num_unstar, a_map=a_map, basis=basis) pt_mode_init = pt_mode_init / \ np.linalg.norm(np.ndarray.flatten(pt_mode_init)) pt += io.m_co[0] * pt_mode_init if io.irr_dim > 1: for i in range(1, io.irr_dim): pt_mode = irrep_tools.projection_odiag(images=images, symmop_list=DG, num_unstar=num_unstar, irrep=irrep, vec=pt_mode_init, index=i, a_map=a_map, basis=basis) pt += io.m_co[i] * \ (pt_mode/np.linalg.norm(np.ndarray.flatten(pt_mode))) p_vec = [ io.p_mag / np.linalg.norm(images[0].lattice.matrix[m, :]) for m in range(0, 3) ] # print pt[3]/np.amax(abs(pt[3])) # print(np.amax(p_vec*(pt[:,:,:]/np.amax(abs(pt))))) images_alt = [] for i in range(numIm): image_copy = images[i].copy() alt_species = image_copy.species perturbed_coords = image_copy.frac_coords + p_vec * (pt[i, :, :] / np.amax(abs(pt))) for j in range(numAtoms): image_copy.replace(j, alt_species[j], perturbed_coords[j]) images_alt.append(image_copy) return images_alt