def test_real_space_basis(): lat = kwant.lattice.honeycomb(norbs=[1, 1]) sym = kwant.TranslationalSymmetry(lat.vec((1, 0)), lat.vec((0, 1))) bulk = kwant.Builder(sym) bulk[[lat.a(0, 0), lat.b(0, 0)]] = 0 bulk[lat.neighbors()] = 1 # Including real space symmetries symmetries = find_builder_symmetries(bulk) hex_group_2D = hexagonal() hex_group_2D = set( PointGroupElement( np.array(s.R).astype(float), s.conjugate, s.antisymmetry, None) for s in hex_group_2D) assert len(symmetries) == len(hex_group_2D) assert all([ s1 in symmetries and s2 in hex_group_2D for s1, s2 in zip(hex_group_2D, symmetries) ]) # Only onsite discrete symmetries symmetries = find_builder_symmetries(bulk, spatial_symmetries=False) onsites = [ PointGroupElement(np.eye(2), True, False, None), # T PointGroupElement(np.eye(2), True, True, None), # P PointGroupElement(np.eye(2), False, True, None), # C PointGroupElement(np.eye(2), False, False, None) ] # I assert len(symmetries) == len(onsites) assert all([ s1 in symmetries and s2 in onsites for s1, s2 in zip(onsites, symmetries) ])
def test_find_builder_discrete_symmetries(): symm_class = ['AI', 'D', 'AIII', 'BDI'] class_dict = { 'AI': ['time_reversal'], 'D': ['particle_hole'], 'AIII': ['chiral'], 'BDI': ['time_reversal', 'particle_hole', 'chiral'] } sym_dict = { 'time_reversal': qsymm.PointGroupElement(np.eye(2), True, False, None), 'particle_hole': qsymm.PointGroupElement(np.eye(2), True, True, None), 'chiral': qsymm.PointGroupElement(np.eye(2), False, True, None) } n = 4 rng = 11 for sym in symm_class: # Random Hamiltonian in the symmetry class h_ons = kwant.rmt.gaussian(n, sym, rng=rng) h_hop = 10 * kwant.rmt.gaussian(2 * n, sym, rng=rng)[:n, n:] # Make a Kwant builder in the symmetry class and find its symmetries lat = kwant.lattice.square(norbs=n) bulk = kwant.Builder(TranslationalSymmetry([1, 0], [0, 1])) bulk[lat(0, 0)] = h_ons bulk[kwant.builder.HoppingKind((1, 0), lat)] = h_hop bulk[kwant.builder.HoppingKind((0, 1), lat)] = h_hop # We need to specify 'prettify=True' here to ensure that we do not end up with # an overcomplete set of symmetries. In some badly conditioned cases sparse=True # or sparse=False may affect how many symmetries are found. builder_symmetries_default = find_builder_symmetries( bulk, spatial_symmetries=True, prettify=True) builder_symmetries_sparse = find_builder_symmetries( bulk, spatial_symmetries=True, prettify=True, sparse=True) builder_symmetries_dense = find_builder_symmetries( bulk, spatial_symmetries=True, prettify=True, sparse=False) assert len(builder_symmetries_default) == len( builder_symmetries_sparse) assert len(builder_symmetries_default) == len(builder_symmetries_dense) # Equality of symmetries ignores unitary part fourfold_rotation = qsymm.PointGroupElement(np.array([[0, 1], [1, 0]]), False, False, None) assert fourfold_rotation in builder_symmetries_default assert fourfold_rotation in builder_symmetries_sparse assert fourfold_rotation in builder_symmetries_dense class_symmetries = class_dict[sym] for class_symmetry in class_symmetries: assert sym_dict[class_symmetry] in builder_symmetries_default assert sym_dict[class_symmetry] in builder_symmetries_sparse assert sym_dict[class_symmetry] in builder_symmetries_dense
def test_basis_ordering(): symm_class = ['AI', 'D', 'AIII', 'BDI'] n = 2 rng = 12 for sym in symm_class: # Make a small finite system in the symmetry class, finalize it and check # that the basis is consistent. h_ons = kwant.rmt.gaussian(n, sym, rng=rng) h_hop = 10 * kwant.rmt.gaussian(2 * n, sym, rng=rng)[:n, n:] lat = kwant.lattice.square(norbs=n) bulk = kwant.Builder(TranslationalSymmetry([1, 0], [0, 1])) bulk[lat(0, 0)] = h_ons bulk[kwant.builder.HoppingKind((1, 0), lat)] = h_hop bulk[kwant.builder.HoppingKind((0, 1), lat)] = h_hop def rect(site): x, y = site.pos return (0 <= x < 2) and (0 <= y < 3) square = kwant.Builder() square.fill(bulk, lambda site: rect(site), (0, 0), max_sites=float('inf')) # Find the symmetries of the square builder_symmetries = find_builder_symmetries(square, spatial_symmetries=False, prettify=True) # Finalize the square, extract Hamiltonian fsquare = square.finalized() ham = fsquare.hamiltonian_submatrix() # Check manually that the found symmetries are in the same basis as the # finalized system for symmetry in builder_symmetries: U = symmetry.U if isinstance(symmetry, qsymm.ContinuousGroupGenerator): assert symmetry.R is None assert allclose(U.dot(ham), ham.dot(U)) else: if symmetry.conjugate: left = U.dot(ham.conj()) else: left = U.dot(ham) if symmetry.antisymmetry: assert allclose(left, -ham.dot(U)) else: assert allclose(left, ham.dot(U))
def test_find_cons_law(): sy = np.array([[0, -1j], [1j, 0]]) n = 3 lat = kwant.lattice.chain(norbs=2*n) syst = kwant.Builder() rng = 1337 ons, hop = random_onsite_hop(n, rng=rng) syst[lat(0)] = np.kron(sy, ons) syst[lat(1)] = np.kron(sy, ons) syst[lat(1), lat(0)] = np.kron(sy, hop) builder_symmetries = find_builder_symmetries(syst, spatial_symmetries=False, prettify=True) onsites = [symm for symm in builder_symmetries if isinstance(symm, qsymm.ContinuousGroupGenerator) and symm.R is None] mham = builder_to_model(syst) assert not any([len(symm.apply(mham)) for symm in onsites])
def test_find_builder_discrete_symmetries(): symm_class = ['AI', 'D', 'AIII', 'BDI'] class_dict = { 'AI': ['time_reversal'], 'D': ['particle_hole'], 'AIII': ['chiral'], 'BDI': ['time_reversal', 'particle_hole', 'chiral'] } sym_dict = { 'time_reversal': qsymm.PointGroupElement(np.eye(2), True, False, None), 'particle_hole': qsymm.PointGroupElement(np.eye(2), True, True, None), 'chiral': qsymm.PointGroupElement(np.eye(2), False, True, None) } n = 4 rng = 11 for sym in symm_class: # Random Hamiltonian in the symmetry class h_ons = kwant.rmt.gaussian(n, sym, rng=rng) h_hop = 10 * kwant.rmt.gaussian(2 * n, sym, rng=rng)[:n, n:] # Make a Kwant builder in the symmetry class and find its symmetries lat = kwant.lattice.square(norbs=n) bulk = kwant.Builder(TranslationalSymmetry([1, 0], [0, 1])) bulk[lat(0, 0)] = h_ons bulk[kwant.builder.HoppingKind((1, 0), lat)] = h_hop bulk[kwant.builder.HoppingKind((0, 1), lat)] = h_hop builder_symmetries = find_builder_symmetries(bulk, spatial_symmetries=True, prettify=True) # Equality of symmetries ignores unitary part fourfold_rotation = qsymm.PointGroupElement(np.array([[0, 1], [1, 0]]), False, False, None) assert fourfold_rotation in builder_symmetries class_symmetries = class_dict[sym] for class_symmetry in class_symmetries: assert sym_dict[class_symmetry] in builder_symmetries