Esempio n. 1
0
def test_site_families():
    syst = builder.Builder()
    fam = builder.SimpleSiteFamily()
    ofam = builder.SimpleSiteFamily()
    yafam = builder.SimpleSiteFamily('another_name')

    syst[fam(0)] = 7
    assert syst[fam(0)] == 7

    assert len(set([fam, ofam, fam('a'), ofam('a'), yafam])) == 3
    syst[fam(1)] = 123
    assert syst[fam(1)] == 123
    assert syst[ofam(1)] == 123
    raises(KeyError, syst.__getitem__, yafam(1))

    # test site families compare equal/not-equal
    assert fam == ofam
    assert fam != yafam
    assert fam != None
    assert fam != 'a'

    # test site families sorting
    fam1 = builder.SimpleSiteFamily(norbs=1)
    fam2 = builder.SimpleSiteFamily(norbs=2)
    assert fam1 < fam2  # string '1' is lexicographically less than '2'
Esempio n. 2
0
def test_attach_lead():
    fam = builder.SimpleSiteFamily(norbs=1)
    fam_noncommensurate = builder.SimpleSiteFamily(name='other')

    syst = builder.Builder()
    syst[fam(1)] = 0
    lead = builder.Builder(VerySimpleSymmetry(-2))
    raises(ValueError, syst.attach_lead, lead)

    lead[fam(0)] = 1
    raises(ValueError, syst.attach_lead, lead)
    lead[fam(1)] = 1
    syst.attach_lead(lead)
    raises(ValueError, syst.attach_lead, lead, fam(5))

    syst = builder.Builder()
    # The tag of the site that is added in the following line is an empty tuple.
    # This simulates a site family that is not commensurate with the symmetry of
    # the lead.  Such sites may be present in the system, as long as there are
    # other sites that will interrupt the lead.
    syst[fam_noncommensurate()] = 2
    syst[fam(1)] = 0
    syst[fam(0)] = 1
    lead[fam(0), fam(1)] = lead[fam(0), fam(2)] = 1
    syst.attach_lead(lead)
    assert len(list(syst.sites())) == 4
    assert set(syst.leads[0].interface) == set([fam(-1), fam(0)])
    syst[fam(-10)] = syst[fam(-11)] = 0
    syst.attach_lead(lead)
    assert set(syst.leads[1].interface) == set([fam(-10), fam(-11)])
    assert len(list(syst.sites())) == 6
    syst.attach_lead(lead, fam(-5))
    assert set(syst.leads[0].interface) == set([fam(-1), fam(0)])

    # add some further-than-nearest-neighbor hoppings
    hop_range = 3
    lead = builder.Builder(
        VerySimpleSymmetry(1),
        conservation_law=np.eye(1),
        time_reversal=np.eye(1),
        particle_hole=np.eye(1),
        chiral=np.eye(1))
    lead[fam(0)] = 1
    for i in range(1, hop_range + 1):
        lead[fam(0), fam(i)] = 1
    syst.attach_lead(lead)
    expanded_lead = syst.leads[-1].builder
    assert expanded_lead.symmetry.period == hop_range
    assert len(list(expanded_lead.sites())) == hop_range
    assert expanded_lead.conservation_law is lead.conservation_law
    assert expanded_lead.time_reversal is lead.time_reversal
    assert expanded_lead.particle_hole is lead.particle_hole
    assert expanded_lead.chiral is lead.chiral

    # check that we can actually finalize the system
    syst.finalized()
Esempio n. 3
0
def test_discrete_symmetries():
    lat = builder.SimpleSiteFamily(name='ccc', norbs=2)
    lat2 = builder.SimpleSiteFamily(name='bla', norbs=1)
    lat3 = builder.SimpleSiteFamily(name='dd', norbs=4)

    cons_law = {lat: np.diag([1, 2]), lat2: 0}
    syst = builder.Builder(
        conservation_law=cons_law,
        time_reversal=(
            lambda site, p: np.exp(1j * p) * np.identity(site.family.norbs)))
    syst[lat(1)] = np.identity(2)
    syst[lat2(1)] = 1

    params = dict(p=0)

    sym = syst.finalized().discrete_symmetry(params=params)
    for proj, should_be in zip(sym.projectors, np.identity(3)):
        assert np.allclose(proj.toarray(), should_be.reshape((3, 1)))
    assert np.allclose(sym.time_reversal.toarray(), np.identity(3))
    syst.conservation_law = lambda site, p: cons_law[site.family]
    sym = syst.finalized().discrete_symmetry(params=params)
    for proj, should_be in zip(sym.projectors, np.identity(3)):
        assert np.allclose(proj.toarray(), should_be.reshape((-1, 1)))

    syst = builder.Builder(conservation_law=np.diag([-1, 1]))
    syst[lat(1)] = np.identity(2)
    sym = syst.finalized().discrete_symmetry()
    for proj, should_be in zip(sym.projectors, np.identity(2)):
        assert np.allclose(proj.toarray(), should_be.reshape((-1, 1)))

    syst = builder.Builder(conservation_law=1)
    syst[lat2(1)] = 0
    sym = syst.finalized().discrete_symmetry()
    [proj] = sym.projectors
    assert np.allclose(proj.toarray(), [[1]])

    syst = kwant.Builder(conservation_law=np.diag([-1, 1, -1, 1]))

    syst[lat3(0)] = np.eye(4)

    sym = syst.finalized().discrete_symmetry()
    p1 = np.zeros((4, 2))
    p1[0, 0] = p1[2, 1] = 1
    assert np.allclose(sym.projectors[0].toarray(), p1)
    p2 = np.zeros((4, 2))
    p2[1, 0] = p2[3, 1] = 1
    assert np.allclose(sym.projectors[1].toarray(), p2)

    # test parameter passing to conservation_law
    syst = builder.Builder(conservation_law=lambda site, b: b)
    syst[lat2(1)] = 0
    sym = syst.finalized().discrete_symmetry(params=dict(a=None, b=1))
    [proj] = sym.projectors
    assert np.allclose(proj.toarray(), [[1]])
Esempio n. 4
0
def test_update():
    lat = builder.SimpleSiteFamily()

    syst = builder.Builder()
    syst[[lat(0, ), lat(1, )]] = 1
    syst[lat(0, ), lat(1, )] = 1

    other_syst = builder.Builder()
    other_syst[[lat(1, ), lat(2, )]] = 2
    other_syst[lat(1, ), lat(2, )] = 1

    lead0 = builder.Builder(VerySimpleSymmetry(-1))
    lead0[lat(0, )] = 1
    lead0[(lat(0, ), lat(1, ))] = 1
    lead0 = builder.BuilderLead(lead0, [lat(0, )])
    syst.leads.append(lead0)

    lead1 = builder.Builder(VerySimpleSymmetry(1))
    lead1[lat(2, )] = 1
    lead1[(lat(2, ), lat(1, ))] = 1
    lead1 = builder.BuilderLead(lead1, [lat(2, )])
    other_syst.leads.append(lead1)

    syst.update(other_syst)
    assert syst.leads == [lead0, lead1]
    expected = sorted([((0, ), 1), ((1, ), 2), ((2, ), 2)])
    assert sorted(((s.tag, v) for s, v in syst.site_value_pairs())) == expected
    expected = sorted([((0, ), (1, ), 1), ((1, ), (2, ), 1)])
    assert (sorted(((a.tag, b.tag, v)
                    for (a, b), v in syst.hopping_value_pairs())) == expected)
Esempio n. 5
0
def test_construction_and_indexing():
    # Without symmetry
    fam = builder.SimpleSiteFamily()
    sites = [fam(0, 0), fam(0, 1), fam(1, 0)]
    hoppings = [(fam(0, 0), fam(0, 1)),
                (fam(0, 1), fam(1, 0)),
                (fam(1, 0), fam(0, 0))]
    unknown_hoppings = [(fam(0, 1), fam(7, 8)),
                        (fam(12, 14), fam(0, 1))]
    check_construction_and_indexing(sites, sites, hoppings, hoppings,
                                    unknown_hoppings)

    # With symmetry
    sites = [fam(0, 0), fam(1, 1), fam(2, 1), fam(4, 2)]
    sites_fd = [fam(0, 0), fam(1, 1), fam(0, 1), fam(0, 2)]
    hoppings = [(fam(0, 0), fam(1, 1)),
                (fam(1, 1), fam(2, 1)),
                (fam(2, 1), fam(4, 2)),
                (fam(4, 2), fam(0, 0))]
    hoppings_fd = [(fam(0, 0), fam(1, 1)),
                   (fam(1, 1), fam(2, 1)),
                   (fam(0, 1), fam(2, 2)),
                   (fam(0, 2), fam(-4, 0))]
    unknown_hoppings = [(fam(0, 0), fam(0, 3)), (fam(0, 4), fam(0, 0)),
                        (fam(0, 0), fam(2, 3)), (fam(2, 4), fam(0, 0)),
                        (fam(4, 2), fam(6, 3)), (fam(6, 4), fam(4, 2))]
    sym = VerySimpleSymmetry(2)
    check_construction_and_indexing(sites, sites_fd, hoppings, hoppings_fd,
                                    unknown_hoppings, sym)
Esempio n. 6
0
 def make_system():
     #        1
     #       / \
     #    3-0---2-4-5  6-7  8
     syst = builder.Builder()
     fam = builder.SimpleSiteFamily()
     syst[(fam(i) for i in range(9))] = None
     syst[[(fam(0), fam(1)), (fam(1), fam(2)), (fam(2), fam(0))]] = None
     syst[[(fam(0), fam(3)), (fam(2), fam(4)), (fam(4), fam(5))]] = None
     syst[fam(6), fam(7)] = None
     return syst
Esempio n. 7
0
def test_neighbors_not_in_single_domain():
    sr = builder.Builder()
    lead = builder.Builder(VerySimpleSymmetry(-1))
    fam = builder.SimpleSiteFamily()
    sr[(fam(x, y) for x in range(3) for y in range(3) if x >= y)] = 0
    sr[builder.HoppingKind((1, 0), fam)] = 1
    sr[builder.HoppingKind((0, 1), fam)] = 1
    lead[(fam(0, y) for y in range(3))] = 0
    lead[((fam(0, y), fam(1, y)) for y in range(3))] = 1
    lead[((fam(0, y), fam(0, y + 1)) for y in range(2))] = 1
    sr.leads.append(builder.BuilderLead(lead, [fam(i, i) for i in range(3)]))
    raises(ValueError, sr.finalized)
Esempio n. 8
0
def check_construction_and_indexing(sites,
                                    sites_fd,
                                    hoppings,
                                    hoppings_fd,
                                    unknown_hoppings,
                                    sym=None):
    fam = builder.SimpleSiteFamily()
    syst = builder.Builder(sym)
    t, V = 1.0j, 0.0
    syst[sites] = V
    for site in sites:
        syst[site] = V
    syst[hoppings] = t
    for hopping in hoppings:
        syst[hopping] = t

    for hopping in unknown_hoppings:
        raises(KeyError, syst.__setitem__, hopping, t)

    assert (fam(5), fam(123)) not in syst
    assert (sites[0], fam(5, 123)) not in syst
    assert (fam(7, 8), sites[0]) not in syst
    for site in sites:
        assert site in syst
        assert syst[site] == V
    for hop in hoppings:
        rev_hop = hop[1], hop[0]
        assert hop in syst
        assert rev_hop in syst
        assert syst[hop] == t
        assert syst[rev_hop] == t.conjugate()

    assert syst.degree(sites[0]) == 2
    assert (sorted(s for s in syst.neighbors(sites[0])) == sorted(
        [sites[1], sites[-1]]))

    del syst[hoppings]
    assert list(syst.hoppings()) == []
    syst[hoppings] = t

    del syst[sites[0]]
    assert sorted(tuple(s) for s in syst.sites()) == sorted(sites_fd[1:])
    assert (sorted(
        (a, b) for a, b in syst.hoppings()) == sorted(hoppings_fd[1:-1]))

    assert (sorted((tuple(site.tag), value)
                   for site, value in syst.site_value_pairs()) == sorted(
                       (tuple(site.tag), syst[site]) for site in syst.sites()))
    assert (sorted((tuple(a.tag), tuple(b.tag), value)
                   for (a, b), value in syst.hopping_value_pairs()) == sorted(
                       (tuple(a.tag), tuple(b.tag), syst[a, b])
                       for a, b in syst.hoppings()))
Esempio n. 9
0
def test_value_equality_and_identity():
    m = ta.array([[1, 2], [3j, 4j]])
    syst = builder.Builder()
    fam = builder.SimpleSiteFamily()

    syst[fam(0)] = m
    syst[fam(1)] = m
    assert syst[fam(1)] is m

    syst[fam(0), fam(1)] = m
    assert syst[fam(1), fam(0)] == m.transpose().conjugate()
    assert syst[fam(0), fam(1)] is m

    syst[fam(1), fam(0)] = m
    assert syst[fam(0), fam(1)] == m.transpose().conjugate()
    assert syst[fam(1), fam(0)] is m
Esempio n. 10
0
def test_hermitian_conjugation():
    def f(i, j, arg):
        i, j = i.tag, j.tag
        if j[0] == i[0] + 1:
            return arg * ta.array([[1, 2j], [3 + 1j, 4j]])
        else:
            raise ValueError

    syst = builder.Builder()
    fam = builder.SimpleSiteFamily()
    syst[fam(0)] = syst[fam(1)] = ta.identity(2)

    syst[fam(0), fam(1)] = f
    assert syst[fam(0), fam(1)] is f
    assert isinstance(syst[fam(1), fam(0)], builder.HermConjOfFunc)
    assert (syst[fam(1), fam(0)](fam(1), fam(0), 2) ==
            syst[fam(0), fam(1)](fam(0), fam(1), 2).conjugate().transpose())
    syst[fam(0), fam(1)] = syst[fam(1), fam(0)]
    assert isinstance(syst[fam(0), fam(1)], builder.HermConjOfFunc)
    assert syst[fam(1), fam(0)] is f
Esempio n. 11
0
def test_hamiltonian_evaluation():
    def f_onsite(site):
        return site.tag[0]

    def f_hopping(a, b):
        a, b = a.tag, b.tag
        return complex(a[0] + b[0], a[1] - b[1])

    tags = [(0, 0), (1, 1), (2, 2), (3, 3)]
    edges = [(0, 1), (0, 2), (0, 3), (1, 2)]

    syst = builder.Builder()
    fam = builder.SimpleSiteFamily()
    sites = [fam(*tag) for tag in tags]
    syst[(fam(*tag) for tag in tags)] = f_onsite
    syst[((fam(*tags[i]), fam(*tags[j])) for (i, j) in edges)] = f_hopping
    fsyst = syst.finalized()

    assert fsyst.graph.num_nodes == len(tags)
    assert fsyst.graph.num_edges == 2 * len(edges)

    for i in range(len(tags)):
        site = fsyst.sites[i]
        assert site in sites
        assert fsyst.hamiltonian(i, i) == syst[site](site)

    for t, h in fsyst.graph:
        tsite = fsyst.sites[t]
        hsite = fsyst.sites[h]
        assert fsyst.hamiltonian(t, h) == syst[tsite, hsite](tsite, hsite)

    # test when user-function raises errors
    def onsite_raises(site):
        raise ValueError()

    def hopping_raises(a, b):
        raise ValueError('error message')

    def test_raising(fsyst, hop):
        a, b = hop
        # exceptions are converted to kwant.UserCodeError and we add our message
        with raises(kwant.UserCodeError) as ctx:
            fsyst.hamiltonian(a, a)
        msg = 'Error occurred in user-supplied value function "onsite_raises"'
        assert msg in ctx.exconly()

        for hop in [(a, b), (b, a)]:
            with raises(kwant.UserCodeError) as ctx:
                fsyst.hamiltonian(*hop)
            msg = ('Error occurred in user-supplied '
                   'value function "hopping_raises"')
            assert msg in ctx.exconly()

    # test with finite system
    new_hop = (fam(-1, 0), fam(0, 0))
    syst[new_hop[0]] = onsite_raises
    syst[new_hop] = hopping_raises
    fsyst = syst.finalized()
    hop = tuple(map(fsyst.sites.index, new_hop))
    test_raising(fsyst, hop)

    # test with infinite system
    inf_syst = kwant.Builder(VerySimpleSymmetry(2))
    for k, v in it.chain(syst.site_value_pairs(), syst.hopping_value_pairs()):
        inf_syst[k] = v
    inf_fsyst = inf_syst.finalized()
    hop = tuple(map(inf_fsyst.sites.index, new_hop))
    test_raising(inf_fsyst, hop)
Esempio n. 12
0
def test_bad_keys():
    def setitem(key):
        syst[key] = None

    fam = builder.SimpleSiteFamily()
    syst = builder.Builder()

    failures = [
        # Invalid single keys
        ([syst.__contains__, syst.__getitem__, setitem, syst.__delitem__],
         [(TypeError, [123, (0, 1), (fam(0), 123), (123, (fam(0)))]),
          (IndexError, [(fam(0), ), (fam(0), fam(1), fam(2))]),
          (ValueError, [(fam(0), fam(0)), (fam(2), fam(2))])]),

        # Hoppings that contain sites that do not belong to the system
        ([syst.__getitem__, setitem,
          syst.__delitem__], [(KeyError, [(fam(0), fam(3)), (fam(2), fam(1)),
                                          (fam(2), fam(3))])]),

        # Sequences containing a bad key.
        ([setitem, syst.__delitem__], [(TypeError, [[fam(0),
                                                     fam(1), 123],
                                                    [fam(0), (fam(1), )],
                                                    [fam(0), (fam(1), fam(2))],
                                                    [(fam(0), fam(1)), (0, 1)],
                                                    [(fam(0), fam(1)),
                                                     (fam(0), 123)],
                                                    [(fam(0), fam(1)),
                                                     (123, fam(0))],
                                                    [(fam(0), fam(1)),
                                                     fam(2)]]),
                                       (IndexError, [[(fam(0), fam(1)),
                                                      (fam(2), )]]),
                                       (ValueError, [[(fam(0), fam(1)),
                                                      (fam(2), fam(2))],
                                                     [(fam(0), fam(0)),
                                                      (fam(1), fam(0))]]),
                                       (KeyError, [[(fam(0), fam(1)),
                                                    (fam(0), fam(3))],
                                                   [(fam(0), fam(1)),
                                                    (fam(2), fam(1))],
                                                   [(fam(1), fam(2)),
                                                    (fam(0), fam(1))]])]),

        # Sites that do not belong to the system, also as part of a
        # sequence
        ([syst.__delitem__],
         [(KeyError, [fam(123), [fam(0), fam(123)], [fam(123),
                                                     fam(1)]])]),

        # Various things that are not sites present in the system.
        ([syst.degree, lambda site: list(syst.neighbors(site))], [(TypeError, [
            123, [0, 1, 2], (0, 1), (fam(0), fam(1)), [fam(0), fam(1)],
            [fam(1), fam(2)], [fam(3), fam(0)]
        ]), (KeyError, [fam(123)])])
    ]

    for funcs, errors in failures:
        for error, keys in errors:
            for key in keys:
                for func in funcs:
                    syst[[fam(0), fam(1)]] = None
                    syst[fam(0), fam(1)] = None
                    try:
                        raises(error, func, key)
                    except AssertionError:
                        print(func, error, key)
                        raise
Esempio n. 13
0
def test_ModesLead_and_SelfEnergyLead():
    lat = builder.SimpleSiteFamily()
    hoppings = [
        builder.HoppingKind((1, 0), lat),
        builder.HoppingKind((0, 1), lat)
    ]
    rng = Random(123)
    L = 5
    t = 1
    energies = [0.9, 1.7]

    syst = builder.Builder()
    for x in range(L):
        for y in range(L):
            syst[lat(x, y)] = 4 * t + rng.random() - 0.5
    syst[hoppings] = -t

    # Attach a lead from the left.
    lead = builder.Builder(VerySimpleSymmetry(-1))
    for y in range(L):
        lead[lat(0, y)] = 4 * t
    lead[hoppings] = -t
    syst.attach_lead(lead)

    # Make the right lead and attach it.
    lead = builder.Builder(VerySimpleSymmetry(1))
    for y in range(L):
        lead[lat(0, y)] = 4 * t
    lead[hoppings] = -t
    syst.attach_lead(lead)

    fsyst = syst.finalized()
    ts = [kwant.smatrix(fsyst, e).transmission(1, 0) for e in energies]

    # Replace lead with it's finalized copy.
    lead = fsyst.leads[1]
    interface = [lat(L - 1, lead.sites[i].tag[1]) for i in range(L)]

    # Re-attach right lead as ModesLead.
    syst.leads[1] = builder.ModesLead(lead.modes, interface)
    fsyst = syst.finalized()
    ts2 = [kwant.smatrix(fsyst, e).transmission(1, 0) for e in energies]
    assert_almost_equal(ts2, ts)

    # Re-attach right lead as ModesLead with old-style modes API
    # that does not take a 'params' keyword parameter.
    syst.leads[1] = builder.ModesLead(
        lambda energy, args: lead.modes(energy, args), interface)
    fsyst = syst.finalized()
    ts2 = [kwant.smatrix(fsyst, e).transmission(1, 0) for e in energies]
    assert_almost_equal(ts2, ts)

    # Re-attach right lead as SelfEnergyLead.
    syst.leads[1] = builder.SelfEnergyLead(lead.selfenergy, interface)
    fsyst = syst.finalized()
    ts2 = [
        kwant.greens_function(fsyst, e).transmission(1, 0) for e in energies
    ]
    assert_almost_equal(ts2, ts)

    # Re-attach right lead as SelfEnergyLead with old-style selfenergy API
    # that does not take a 'params' keyword parameter.
    syst.leads[1] = builder.SelfEnergyLead(
        lambda energy, args: lead.selfenergy(energy, args), interface)
    fsyst = syst.finalized()
    ts2 = [
        kwant.greens_function(fsyst, e).transmission(1, 0) for e in energies
    ]
    assert_almost_equal(ts2, ts)

    # Append a virtual (=zero self energy) lead.  This should have no effect.
    # Also verifies that the selfenergy callback function can return exotic
    # arraylikes.
    syst.leads.append(
        builder.SelfEnergyLead(lambda *args: list(ta.zeros((L, L))),
                               interface))
    fsyst = syst.finalized()
    ts2 = [
        kwant.greens_function(fsyst, e).transmission(1, 0) for e in energies
    ]
    assert_almost_equal(ts2, ts)