def get_clusters_rel_by_symmetry(cluster, symmetry='d4'): """ Return all distinct clusters related to the initial cluster by symmetry. :param cluster: geometry object representing a cluster :param symmetry: TODO implement others besides D4 :return cluster_symm_partners: a list of geometry objects, including the initial cluster which are related by the specified symmetry """ rot_fn = symm.getRotFn(4) refl_fn = symm.getReflFn([0, 1]) cluster_symm_partners = [cluster] # list coordinates of all D4 symmetries places_round = 14 xys_list = [] xys_list.append(np.round(rot_fn(cluster.xlocs, cluster.ylocs), places_round)) xys_list.append(np.round(rot_fn(xys_list[0][0, :], xys_list[0][1, :]), places_round)) xys_list.append(np.round(rot_fn(xys_list[1][0, :], xys_list[1][1, :]), places_round)) xys_list.append(np.round(refl_fn(cluster.xlocs, cluster.ylocs), places_round)) xys_list.append(np.round(refl_fn(xys_list[0][0, :], xys_list[0][1, :]), places_round)) xys_list.append(np.round(refl_fn(xys_list[1][0, :], xys_list[1][1, :]), places_round)) xys_list.append(np.round(refl_fn(xys_list[2][0, :], xys_list[2][1, :]), places_round)) # add distinct clusters to a list for xys in xys_list: c = geom.Geometry.createNonPeriodicGeometry(xys[0, :], xys[1, :]) c.permute_sites(c.get_sorting_permutation()) if not [h for h in cluster_symm_partners if h.isequal_adjacency(c)]: cluster_symm_partners.append(c) return cluster_symm_partners
def test_full_symm_3byb3(self): U = 20 * (np.random.rand() - 0.5) t = np.random.rand() gm = geom.Geometry.createSquareGeometry(3, 3, 0, 0, bc1_open=False, bc2_open=False) model = ed_fermions.fermions(gm, U, t, ns=np.array([2, 2])) # no symmetry hamiltonian_full = model.createH(projector=model.n_projector) eig_vals_full, eig_vects_full = model.diagH(hamiltonian_full) # rotational symmetry cx, cy = model.geometry.get_center_of_mass() rot_fn = symm.getRotFn(4, cx=cx, cy=cy) rot_cycles, max_cycle_len_rot = symm.findSiteCycles( rot_fn, model.geometry) rot_op = model.n_projector.dot( model.get_xform_op(rot_cycles).dot( model.n_projector.conj().transpose())) # reflection symmetry refl_fn = symm.getReflFn(np.array([[0], [1]]), cx=cx, cy=cy) refl_cycles, max_cycle_len_refl = symm.findSiteCycles( refl_fn, model.geometry) refl_op = model.n_projector.dot( model.get_xform_op(refl_cycles).dot( model.n_projector.conj().transpose())) # translational symmetry tx_fn = symm.getTranslFn(np.array([[1], [0]])) tx_cycles, tx_max = symm.findSiteCycles(tx_fn, model.geometry) tx_op_full = model.get_xform_op(tx_cycles) tx_op = model.n_projector.dot( tx_op_full.dot(model.n_projector.conj().transpose())) ty_fn = symm.getTranslFn((np.array([[0], [1]]))) ty_cycles, ty_max = symm.findSiteCycles(ty_fn, model.geometry) ty_op_full = model.get_xform_op(ty_cycles) ty_op = model.n_projector.dot( ty_op_full.dot(model.n_projector.conj().transpose())) symm_projs = symm.getC4V_and_3byb3(rot_op, refl_op, tx_op, ty_op) eig_vals_sectors = [] for ii, proj in enumerate(symm_projs): h_sector = model.createH(projector=proj.dot(model.n_projector)) eig_vals_sector, eig_vects_sector = model.diagH(h_sector) eig_vals_sectors.append(eig_vals_sector) # why only accurate to 10 decimal places? eigs_all_sectors = np.sort(np.concatenate(eig_vals_sectors)) max_diff = np.abs(eig_vals_full - eigs_all_sectors).max() self.assertAlmostEqual(max_diff, 0, 10)
def test_d4_symm(self): """ Test d4 symmetry by diagonalizing random spin system with and without it :return: """ cluster = geom.Geometry.createSquareGeometry(3, 3, 0, 0, bc1_open=False, bc2_open=False) jx = np.random.rand() jy = np.random.rand() jz = np.random.rand() hx = np.random.rand() hy = np.random.rand() hz = np.random.rand() # diagonalize full hamiltonian spin_model = tvi.spinSystem(cluster, jx, jy, jz, hx, hy, hz, use_ryd_detunes=0) hamiltonian_full = spin_model.createH() eig_vals_full, eig_vects_full = spin_model.diagH(hamiltonian_full) # use rotationl symmetry cx, cy = spin_model.geometry.get_center_of_mass() rot_fn = symm.getRotFn(4, cx=cx, cy=cy) rot_cycles, max_cycle_len_rot = symm.findSiteCycles( rot_fn, spin_model.geometry) rot_op = spin_model.get_xform_op(rot_cycles) refl_fn = symm.getReflFn(np.array([0, 1]), cx=cx, cy=cy) refl_cycles, max_cycle_len_ref = symm.findSiteCycles( refl_fn, spin_model.geometry) refl_op = spin_model.get_xform_op(refl_cycles) symm_projs = symm.getD4Projectors(rot_op, refl_op) eig_vals_sectors = [] for ii, proj in enumerate(symm_projs): h_sector = spin_model.createH(projector=proj) eig_vals_sector, eig_vects_sector = spin_model.diagH(h_sector) eig_vals_sectors.append(eig_vals_sector) # why only accurate to 10 decimal places? eigs_all_sectors = np.sort(np.concatenate(eig_vals_sectors)) max_diff = np.abs(eig_vals_full - eigs_all_sectors).max() self.assertAlmostEqual(max_diff, 0, 10)
def test_d2_symmetry_3by3(self): """ Test D2 symmetry (generated by 180 degree rotation and a reflection) on a 3x3 Hubbard cluster with open boundary conditions. :return: """ # todo: do all number sectors U = 20 * (np.random.rand() - 0.5) t = np.random.rand() gm = geom.Geometry.createSquareGeometry(3, 3, 0, 0, bc1_open=False, bc2_open=False) model = ed_fermions.fermions(gm, U, t, ns=np.array([3, 4]), nspecies=2) # no symmetry hamiltonian_full = model.createH(projector=model.n_projector) eig_vals_full, eig_vects_full = model.diagH(hamiltonian_full) # rotational symmetry cx, cy = model.geometry.get_center_of_mass() rot_fn = symm.getRotFn(2, cx=cx, cy=cy) rot_cycles, max_cycle_len_rot = symm.findSiteCycles( rot_fn, model.geometry) rot_op_full = model.get_xform_op(rot_cycles) rot_op = model.n_projector.dot( rot_op_full.dot(model.n_projector.conj().transpose())) # reflection symmetry refl_fn = symm.getReflFn(np.array([[0], [1]]), cx=cx, cy=cy) refl_cycles, max_cycle_len_refl = symm.findSiteCycles( refl_fn, model.geometry) refl_op_full = model.get_xform_op(refl_cycles) refl_op = model.n_projector.dot( refl_op_full.dot(model.n_projector.conj().transpose())) symm_projs = symm.getD2Projectors(rot_op, refl_op) eig_vals_sectors = [] for ii, proj in enumerate(symm_projs): h_sector = model.createH(projector=proj.dot(model.n_projector)) eig_vals_sector, eig_vects_sector = model.diagH(h_sector) eig_vals_sectors.append(eig_vals_sector) # why only accurate to 10 decimal places? eigs_all_sectors = np.sort(np.concatenate(eig_vals_sectors)) max_diff = np.abs(eig_vals_full - eigs_all_sectors).max() self.assertAlmostEqual(max_diff, 0, 10)
def test_d3_symm_6sites(self): adjacency_mat = np.array([[0, 1, 0, 1, 0, 0], [1, 0, 1, 1, 1, 0], [0, 1, 0, 0, 1, 0], [1, 1, 0, 0, 1, 1], [0, 1, 1, 1, 0, 1], [0, 0, 0, 1, 1, 0]]) cluster = geom.Geometry.createNonPeriodicGeometry( xlocs=(0, 1, 2, 0.5, 1.5, 1), ylocs=(0, 0, 0, np.sqrt(3) / 2, np.sqrt(3) / 2, np.sqrt(3)), adjacency_mat=adjacency_mat) jx = np.random.rand() jy = np.random.rand() jz = np.random.rand() hx = np.random.rand() hy = np.random.rand() hz = np.random.rand() # diagonalize full hamiltonian spin_model = tvi.spinSystem(cluster, jx, jy, jz, hx, hy, hz, use_ryd_detunes=0) hamiltonian_full = spin_model.createH() eig_vals_full, eig_vects_full = spin_model.diagH(hamiltonian_full) # use rotationl symmetry # triangle center cx, cy = 1, 1 / np.sqrt(3) rot_fn = symm.getRotFn(3, cx=cx, cy=cy) rot_cycles, max_cycle_len_rot = symm.findSiteCycles( rot_fn, spin_model.geometry) rot_op = spin_model.get_xform_op(rot_cycles) refl_fn = symm.getReflFn(np.array([0, 1]), cx=cx, cy=cy) refl_cycles, max_cycle_len_ref = symm.findSiteCycles( refl_fn, spin_model.geometry) refl_op = spin_model.get_xform_op(refl_cycles) symm_projs = symm.getD3Projectors(rot_op, refl_op) eig_vals_sectors = [] for ii, proj in enumerate(symm_projs): h_sector = spin_model.createH(projector=proj) eig_vals_sector, eig_vects_sector = spin_model.diagH(h_sector) eig_vals_sectors.append(eig_vals_sector) eigs_all_sectors = np.sort(np.concatenate(eig_vals_sectors)) max_diff = np.abs(eig_vals_full - eigs_all_sectors).max() self.assertAlmostEqual(max_diff, 0, 12)
def test_d3_symm_3sites(self): """ Test d3 symmetry by diagonalizing random spin system with and without it :return: """ # adjacency_mat = np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]]) # cluster = geom.Geometry.createNonPeriodicGeometry(xlocs=(0,0.5,1), ylocs=(0,np.sqrt(3)/2,0), adjacency_mat=adjacency_mat) cluster = geom.Geometry.createRegularPolygonGeometry(3) jx = np.random.rand() jy = np.random.rand() jz = np.random.rand() hx = np.random.rand() hy = np.random.rand() hz = np.random.rand() # diagonalize full hamiltonian spin_model = tvi.spinSystem(cluster, jx, jy, jz, hx, hy, hz, use_ryd_detunes=0) hamiltonian_full = spin_model.createH() eig_vals_full, eig_vects_full = spin_model.diagH(hamiltonian_full) # use rotationl symmetry rot_fn = symm.getRotFn(3) rot_cycles, max_cycle_len_rot = symm.findSiteCycles( rot_fn, spin_model.geometry) rot_op = spin_model.get_xform_op(rot_cycles) refl_fn = symm.getReflFn(np.array([0, 1])) refl_cycles, max_cycle_len_ref = symm.findSiteCycles( refl_fn, spin_model.geometry) refl_op = spin_model.get_xform_op(refl_cycles) symm_projs = symm.getD3Projectors(rot_op, refl_op) eig_vals_sectors = [] for ii, proj in enumerate(symm_projs): h_sector = spin_model.createH(projector=proj) eig_vals_sector, eig_vects_sector = spin_model.diagH(h_sector) eig_vals_sectors.append(eig_vals_sector) # why only accurate to 10 decimal places? eigs_all_sectors = np.sort(np.concatenate(eig_vals_sectors)) max_diff = np.abs(eig_vals_full - eigs_all_sectors).max() self.assertAlmostEqual(max_diff, 0, 12)
def test_get_refl_fn(self): """ Test coordinate reflection function :return: """ refl_vect = np.array([[1.0], [1.0]]) refl_fn = ed_symmetry.getReflFn(refl_vect, cx=-1.0, cy=2.0) x = np.array([3.0]) y = np.array([5.0]) x_refl, y_refl = refl_fn(x, y) x_refl_expected = np.array([2.0]) y_refl_expected = np.array([6.0]) self.assertAlmostEqual(np.linalg.norm(x_refl - x_refl_expected), 0, 14) self.assertAlmostEqual(np.linalg.norm(y_refl - y_refl_expected), 0, 14)
def test_d7_symm_7sites(self): cluster = geom.Geometry.createRegularPolygonGeometry(7) jx = np.random.rand() jy = np.random.rand() jz = np.random.rand() hx = np.random.rand() hy = np.random.rand() hz = np.random.rand() # diagonalize full hamiltonian spin_model = tvi.spinSystem(cluster, jx, jy, jz, hx, hy, hz, use_ryd_detunes=0) hamiltonian_full = spin_model.createH() eig_vals_full, eig_vects_full = spin_model.diagH(hamiltonian_full) # use rotationl symmetry rot_fn = symm.getRotFn(7) rot_cycles, max_cycle_len_rot = symm.findSiteCycles( rot_fn, spin_model.geometry) rot_op = spin_model.get_xform_op(rot_cycles) refl_fn = symm.getReflFn(np.array([0, 1])) refl_cycles, max_cycle_len_ref = symm.findSiteCycles( refl_fn, spin_model.geometry) refl_op = spin_model.get_xform_op(refl_cycles) symm_projs = symm.getD6Projectors(rot_op, refl_op) eig_vals_sectors = [] for ii, proj in enumerate(symm_projs): h_sector = spin_model.createH(projector=proj) eig_vals_sector, eig_vects_sector = spin_model.diagH(h_sector) eig_vals_sectors.append(eig_vals_sector) eigs_all_sectors = np.sort(np.concatenate(eig_vals_sectors)) max_diff = np.abs(eig_vals_full - eigs_all_sectors).max() self.assertAlmostEqual(max_diff, 0, 14)
def test_full_symm_3x3(self): cluster = geom.Geometry.createSquareGeometry(3, 3, 0, 0, bc1_open=False, bc2_open=False) jx = np.random.rand() jy = np.random.rand() jz = np.random.rand() hx = np.random.rand() hy = np.random.rand() hz = np.random.rand() # diagonalize full hamiltonian spin_model = tvi.spinSystem(cluster, jx, jy, jz, hx, hy, hz, use_ryd_detunes=0) hamiltonian_full = spin_model.createH() eig_vals_full, eig_vects_full = spin_model.diagH(hamiltonian_full) xtransl_fn = symm.getTranslFn(np.array([[1], [0]])) xtransl_cycles, max_cycle_len_translx = symm.findSiteCycles( xtransl_fn, spin_model.geometry) tx_op = spin_model.get_xform_op(xtransl_cycles) # y-translations ytransl_fn = symm.getTranslFn(np.array([[0], [1]])) ytransl_cycles, max_cycle_len_transly = symm.findSiteCycles( ytransl_fn, spin_model.geometry) ty_op = spin_model.get_xform_op(ytransl_cycles) # rotation cx, cy = spin_model.geometry.get_center_of_mass() rot_fn = symm.getRotFn(4, cx=cx, cy=cy) rot_cycles, max_cycle_len_rot = symm.findSiteCycles( rot_fn, spin_model.geometry) rot_op = spin_model.get_xform_op(rot_cycles) # reflection # reflection about y-axis refl_fn = symm.getReflFn(np.array([0, 1]), cx=cx, cy=cy) refl_cycles, max_cycle_len_refl = symm.findSiteCycles( refl_fn, spin_model.geometry) refl_op = spin_model.get_xform_op(refl_cycles) symm_projs = symm.getC4V_and_3byb3(rot_op, refl_op, tx_op, ty_op) eig_vals_sectors = [] for ii, proj in enumerate(symm_projs): h_sector = spin_model.createH(projector=proj) eig_vals_sector, eig_vects_sector = spin_model.diagH(h_sector) eig_vals_sectors.append(eig_vals_sector) # why only accurate to 10 decimal places? eigs_all_sectors = np.sort(np.concatenate(eig_vals_sectors)) max_diff = np.abs(eig_vals_full - eigs_all_sectors).max() self.assertAlmostEqual(max_diff, 0, 10)