Ejemplo n.º 1
0
def test_HoppingKind():
    g = kwant.lattice.general(ta.identity(3), name="some_lattice")
    h = kwant.lattice.general(ta.identity(3), name="another_lattice")
    sym = kwant.TranslationalSymmetry((0, 2, 0))
    sys = builder.Builder(sym)
    sys[((h if max(x, y, z) % 2 else g)(x, y, z) for x in range(4) for y in range(2) for z in range(4))] = None
    for delta, ga, gb, n in [
        ((1, 0, 0), g, h, 4),
        ((1, 0, 0), h, g, 7),
        ((0, 1, 0), g, h, 1),
        ((0, 4, 0), h, h, 21),
        ((0, 0, 1), g, h, 4),
    ]:
        ph = list(builder.HoppingKind(delta, ga, gb)(sys))
        assert_equal(len(ph), n)
        ph = set(ph)
        assert_equal(len(ph), n)

        ph2 = list((sym.to_fd(b, a) for a, b in builder.HoppingKind(ta.negative(delta), gb, ga)(sys)))
        assert_equal(len(ph2), n)
        ph2 = set(ph2)
        assert_equal(ph2, ph)

        for a, b in ph:
            assert a.family == ga
            assert b.family == gb
            assert sym.to_fd(a) == a
            assert_equal(a.tag - b.tag, delta)
Ejemplo n.º 2
0
def test_closest():
    rng = ensure_rng(10)
    for sym_dim in range(1, 4):
        for space_dim in range(sym_dim, 4):
            lat = kwant.lattice.general(ta.identity(space_dim))

            # Choose random periods.
            while True:
                periods = rng.randint(-10, 11, (sym_dim, space_dim))
                if np.linalg.det(np.dot(periods, periods.T)) > 0.1:
                    # Periods are reasonably linearly independent.
                    break
            syst = builder.Builder(kwant.TranslationalSymmetry(*periods))

            for tag in rng.randint(-30, 31, (4, space_dim)):
                # Add site and connect it to the others.
                old_sites = list(syst.sites())
                new_site = lat(*tag)
                syst[new_site] = None
                syst[((new_site, os) for os in old_sites)] = None

                # Test consistency with fill().
                for point in 200 * rng.random_sample((10, space_dim)) - 100:
                    closest = syst.closest(point)
                    dist = closest.pos - point
                    dist = ta.dot(dist, dist)
                    syst2 = builder.Builder()
                    syst2.fill(syst, inside_disc(point, 2 * dist), closest)
                    assert syst2.closest(point) == closest
                    for site in syst2.sites():
                        dd = site.pos - point
                        dd = ta.dot(dd, dd)
                        assert dd >= 0.999999 * dist
Ejemplo n.º 3
0
def test_special_constructors():
    for dtype in dtypes:
        for shape in some_shapes:
            assert ta.zeros(shape, dtype) == np.zeros(shape, dtype)
            assert ta.ones(shape, dtype) == np.ones(shape, dtype)
        for n in [0, 1, 2, 3, 17]:
            assert ta.identity(n, dtype) == np.identity(n, dtype)
Ejemplo n.º 4
0
def test_special_constructors():
    for dtype in dtypes:
        for shape in some_shapes:
            assert_equal(ta.zeros(shape, dtype), np.zeros(shape, dtype))
            assert_equal(ta.ones(shape, dtype), np.ones(shape, dtype))
        for n in [0, 1, 2, 3, 17]:
            assert_equal(ta.identity(n, dtype), np.identity(n, dtype))
Ejemplo n.º 5
0
def time_reversal(realspace_dim, U=None, spin=None):
    """Return a time-reversal symmetry operator

    parameters
    ----------
    realspace_dim : int
        Realspace dimension
    U: ndarray (optional)
        The unitary action on the Hilbert space.
        May be None, to be able to treat symmetry candidates.
    spin : float or sequence of arrays (optional)
        Spin representation to use for the unitary action of the time reversal
        operator. If float is provided, it should be integer or half-integer
        specifying the spin representation in the standard basis, see `spin_matrices`.
        Otherwise a sequence of 3 arrays of identical square size must be provided
        representing 3 components of the angular momentum operator. The unitary action
        of time-reversal operator is `U = exp(-i π s_y)`. Only one of `U` and `spin`
        may be provided.

    Returns
    -------
    T : PointGroupElement
    """
    if U is not None and spin is not None:
        raise ValueError('Only one of `U` and `spin` may be provided.')
    if spin is not None:
        U = spin_rotation(np.pi * np.array([0, 1, 0]), spin)
    R = ta.identity(realspace_dim, int)
    return PointGroupElement(R, conjugate=True, antisymmetry=False, U=U)
Ejemplo n.º 6
0
 def identity(self):
     """Return identity element with the same structure as self."""
     dim = self.R.shape[0]
     R = ta.identity(dim, int)
     if self.U is not None:
         U = np.eye(self.U.shape[0])
     else:
         U = None
     return PointGroupElement(R, False, False, U)
Ejemplo n.º 7
0
def test_invalid_HoppingKind():
    g = kwant.lattice.general(ta.identity(3))
    h = kwant.lattice.general(np.identity(3)[:-1])  # 2D lattice in 3D

    delta = (1, 0, 0)

    # families have incompatible tags
    with raises(ValueError):
        builder.HoppingKind(delta, g, h)

    # delta is incompatible with tags
    with raises(ValueError):
        builder.HoppingKind(delta, h)
Ejemplo n.º 8
0
def test_HoppingKind():
    g = kwant.lattice.general(ta.identity(3), name='some_lattice')
    h = kwant.lattice.general(ta.identity(3), name='another_lattice')
    sym = kwant.TranslationalSymmetry((0, 2, 0))
    syst = builder.Builder(sym)
    syst[((h if max(x, y, z) % 2 else g)(x, y, z)
         for x in range(4) for y in range(2) for z in range(4))] = None
    for delta, ga, gb, n in [((1, 0, 0), g, h, 4),
                             ((1, 0, 0), h, g, 7),
                             ((0, 1, 0), g, h, 1),
                             ((0, 4, 0), h, h, 21),
                             ((0, 0, 1), g, h, 4)]:
        ph = list(builder.HoppingKind(delta, ga, gb)(syst))
        assert len(ph) == n
        ph = set(ph)
        assert len(ph) == n

        ph2 = list((
                sym.to_fd(b, a) for a, b in
                builder.HoppingKind(ta.negative(delta), gb, ga)(syst)))
        assert len(ph2) == n
        ph2 = set(ph2)
        assert ph2 == ph

        for a, b in ph:
            assert a.family == ga
            assert b.family == gb
            assert sym.to_fd(a) == a
            assert a.tag - b.tag == delta

        # test hashability and equality
        hk = builder.HoppingKind((1, 0, 0), g)
        hk2 = builder.HoppingKind((1, 0, 0), g)
        hk3 = builder.HoppingKind((1, 0, 0), g, h)
        assert hk == hk2
        assert hash(hk) == hash(hk2)
        assert hk != hk3
        assert hash(hk) != hash(hk3)
        assert len({hk: 0, hk2:1, hk3: 2}) == 2
Ejemplo n.º 9
0
def test_HoppingKind():
    g = kwant.lattice.general(ta.identity(3), name='some_lattice')
    h = kwant.lattice.general(ta.identity(3), name='another_lattice')
    sym = kwant.TranslationalSymmetry((0, 2, 0))
    syst = builder.Builder(sym)
    syst[((h if max(x, y, z) % 2 else g)(x, y, z)
         for x in range(4) for y in range(2) for z in range(4))] = None
    for delta, ga, gb, n in [((1, 0, 0), g, h, 4),
                             ((1, 0, 0), h, g, 7),
                             ((0, 1, 0), g, h, 1),
                             ((0, 4, 0), h, h, 21),
                             ((0, 0, 1), g, h, 4)]:
        ph = list(builder.HoppingKind(delta, ga, gb)(syst))
        assert len(ph) == n
        ph = set(ph)
        assert len(ph) == n

        ph2 = list((
                sym.to_fd(b, a) for a, b in
                builder.HoppingKind(ta.negative(delta), gb, ga)(syst)))
        assert len(ph2) == n
        ph2 = set(ph2)
        assert ph2 == ph

        for a, b in ph:
            assert a.family == ga
            assert b.family == gb
            assert sym.to_fd(a) == a
            assert a.tag - b.tag == delta

        # test hashability and equality
        hk = builder.HoppingKind((1, 0), g)
        hk2 = builder.HoppingKind((1, 0), g)
        hk3 = builder.HoppingKind((1, 0), g, h)
        assert hk == hk2
        assert hash(hk) == hash(hk2)
        assert hk != hk3
        assert hash(hk) != hash(hk3)
        assert len({hk: 0, hk2:1, hk3: 2}) == 2
Ejemplo n.º 10
0
def test_builder_with_symmetry():
    g = kwant.lattice.general(ta.identity(3))
    sym = kwant.TranslationalSymmetry((0, 0, 3), (0, 2, 0))
    sys = builder.Builder(sym)

    t, V = 1.0j, 0.0
    hoppings = [
        (g(5, 0, 0), g(0, 5, 0)),
        (g(0, 5, 0), g(0, 0, 5)),
        (g(0, 0, 5), g(5, 0, 0)),
        (g(0, 3, 0), g(0, 0, 5)),
        (g(0, 7, -6), g(5, 6, -6)),
    ]
    hoppings_fd = [
        (g(5, 0, 0), g(0, 5, 0)),
        (g(0, 1, 0), g(0, -4, 5)),
        (g(0, 0, 2), g(5, 0, -3)),
        (g(0, 1, 0), g(0, -2, 5)),
        (g(0, 1, 0), g(5, 0, 0)),
    ]

    sys[(a for a, b in hoppings)] = V
    sys[hoppings] = t

    # TODO: Once Tinyarray supports "<" the conversion to tuple can be removed.
    assert_equal(sorted(tuple(site.tag) for site in sys.sites()), sorted(set(tuple(hop[0].tag) for hop in hoppings_fd)))
    for sites in hoppings_fd:
        for site in sites:
            assert site in sys
            assert_equal(sys[site], V)

    # TODO: Once Tinyarray supports "<" the conversion to tuple can be removed.
    assert_equal(
        sorted((tuple(a.tag), tuple(b.tag)) for a, b in sys.hoppings()),
        sorted((tuple(a.tag), tuple(b.tag)) for a, b in hoppings_fd),
    )
    for hop in hoppings_fd:
        rhop = hop[1], hop[0]
        assert hop in sys
        assert rhop in sys
        assert_equal(sys[hop], t)
        assert_equal(sys[rhop], t.conjugate())

    del sys[g(0, 6, -4), g(0, 11, -9)]
    assert (g(0, 1, 0), g(0, -4, 5)) not in sys

    del sys[g(0, 3, -3)]
    assert_equal(list((a.tag, b.tag) for a, b in sys.hoppings()), [((0, 0, 2), (5, 0, -3))])
Ejemplo n.º 11
0
def inversion(realspace_dim, U=None):
    """Return an inversion operator

    parameters
    ----------
    realspace_dim : int
        Realspace dimension
    U: ndarray (optional)
        The unitary action on the Hilbert space.
        May be None, to be able to treat symmetry candidates

    Returns
    -------
    P : PointGroupElement
    """
    R = -ta.identity(realspace_dim, int)
    return PointGroupElement(R, conjugate=False, antisymmetry=False, U=U)
Ejemplo n.º 12
0
def test_builder_with_symmetry():
    g = kwant.lattice.general(ta.identity(3))
    sym = kwant.TranslationalSymmetry((0, 0, 3), (0, 2, 0))
    syst = builder.Builder(sym)

    t, V = 1.0j, 0.0
    hoppings = [(g(5, 0, 0), g(0, 5, 0)),
                (g(0, 5, 0), g(0, 0, 5)),
                (g(0, 0, 5), g(5, 0, 0)),
                (g(0, 3, 0), g(0, 0, 5)),
                (g(0, 7, -6), g(5, 6, -6))]
    hoppings_fd = [(g(5, 0, 0), g(0, 5, 0)),
                   (g(0, 1, 0), g(0, -4, 5)),
                   (g(0, 0, 2), g(5, 0, -3)),
                   (g(0, 1, 0), g(0, -2, 5)),
                   (g(0, 1, 0), g(5, 0, 0))]

    syst[(a for a, b in hoppings)] = V
    syst[hoppings] = t

    # TODO: Once Tinyarray supports "<" the conversion to tuple can be removed.
    assert (sorted(tuple(site.tag) for site in syst.sites()) ==
            sorted(set(tuple(hop[0].tag) for hop in hoppings_fd)))
    for sites in hoppings_fd:
        for site in sites:
            assert site in syst
            assert syst[site] == V

    # TODO: Once Tinyarray supports "<" the conversion to tuple can be removed.
    assert (sorted((tuple(a.tag), tuple(b.tag)) for a, b in syst.hoppings()) ==
            sorted((tuple(a.tag), tuple(b.tag)) for a, b in hoppings_fd))
    for hop in hoppings_fd:
        rhop = hop[1], hop[0]
        assert hop in syst
        assert rhop in syst
        assert syst[hop] == t
        assert syst[rhop] == t.conjugate()

    del syst[g(0, 6, -4), g(0, 11, -9)]
    assert (g(0, 1, 0), g(0, -4, 5)) not in syst

    del syst[g(0, 3, -3)]
    assert (list((a.tag, b.tag) for a, b in syst.hoppings()) == [((0, 0, 2),
                                                                  (5, 0, -3))])
Ejemplo n.º 13
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

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

    sys[fam(0), fam(1)] = f
    assert sys[fam(0), fam(1)] is f
    assert isinstance(sys[fam(1), fam(0)], builder.HermConjOfFunc)
    assert_equal(sys[fam(1), fam(0)](fam(1), fam(0), 2), sys[fam(0), fam(1)](fam(0), fam(1), 2).conjugate().transpose())
    sys[fam(0), fam(1)] = sys[fam(1), fam(0)]
    assert isinstance(sys[fam(0), fam(1)], builder.HermConjOfFunc)
    assert sys[fam(1), fam(0)] is f
Ejemplo n.º 14
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
Ejemplo n.º 15
0
def identity(dim, shape=None):
    """Return identity operator with appropriate shape.

    Parameters
    ----------
    dim : int
        Dimension of real space.
    shape : int (optional)
        Size of the unitary part of the operator.
        If not provided, U is set to None.

    Returns
    -------
    id : PointGroupElement
    """
    R = ta.identity(dim, int)
    if shape is not None:
        U = np.eye(shape)
    else:
        U = None
    return PointGroupElement(R, False, False, U)
def test_operator_construction():
    lat, syst = _random_square_system(3)
    fsyst = syst.finalized()
    N = len(fsyst.sites)

    # test construction failure if norbs not given
    latnone = kwant.lattice.chain()
    syst[latnone(0)] = 1
    for A in opservables:
        raises(ValueError, A, syst.finalized())
    del syst[latnone(0)]

    # test construction failure when dimensions of onsite do not match
    for A in opservables:
        raises(ValueError, A, fsyst, onsite=np.eye(2))

    # test that error is raised when input array is the wrong size
    for A in opservables:
        a = A(fsyst)
        kets = list(map(np.ones, [(0, ), (N - 1, ), (N + 1, ), (N, 1)]))
        for ket in kets:
            raises(ValueError, a, ket)
            raises(ValueError, a, ket, ket)
            raises(ValueError, a.act, ket)
            raises(ValueError, a.act, ket, ket)

    # Test failure on non-hermitian
    for A in (ops.Density, ops.Current, ops.Source):
        raises(ValueError, A, fsyst, 1j)

    # Test output dtype
    ket = np.ones(len(fsyst.sites))
    for A in (ops.Density, ops.Current, ops.Source):
        a = A(fsyst)
        a_nonherm = A(fsyst, check_hermiticity=False)
        assert a(ket, ket).dtype == np.complex128
        assert a(ket).dtype == np.float64
        assert a_nonherm(ket, ket).dtype == np.complex128
        assert a_nonherm(ket).dtype == np.complex128

    # test construction with different numbers of orbitals
    lat2 = kwant.lattice.chain(norbs=2)
    extra_sites = [lat2(i) for i in range(N)]
    syst[extra_sites] = np.eye(2)
    syst[zip(fsyst.sites, extra_sites)] = ta.matrix([1, 1])
    for A in opservables:
        raises(ValueError, A, syst.finalized(), onsite=np.eye(2))
        A(syst.finalized())
        A.onsite == np.eye(2)
    del syst[extra_sites]

    check = [(ops.Density, np.arange(N).reshape(-1, 1), ta.identity(1)),
             (ops.Current, np.array(list(fsyst.graph)), ta.identity(1)),
             (ops.Source, np.arange(N).reshape(-1, 1), ta.identity(1))]

    # test basic construction
    for A, where, onsite in check:
        a = A(fsyst)
        assert np.all(np.asarray(a.where) == where)
        assert all(a.onsite == onsite for i in range(N))

    # test construction with dict `onsite`
    for A in opservables:
        B = A(fsyst, {lat: 1})
        assert all(B.onsite(i) == 1 for i in range(N))

    # test construction with a functional onsite
    for A in opservables:
        B = A(fsyst, lambda site: site.pos[0])  # x-position operator
        assert all(B.onsite(i) == fsyst.sites[i].pos[0] for i in range(N))

    # test construction with `where` given by a sequence
    where = [lat(2, 2), lat(1, 1)]
    fwhere = tuple(fsyst.id_by_site[s] for s in where)
    A = ops.Density(fsyst, where=where)
    assert np.all(np.asarray(A.where).reshape(-1) == fwhere)

    where = [(lat(2, 2), lat(1, 2)), (lat(0, 0), lat(0, 1))]
    fwhere = np.asarray([(fsyst.id_by_site[a], fsyst.id_by_site[b])
                         for a, b in where])
    A = ops.Current(fsyst, where=where)
    assert np.all(np.asarray(A.where) == fwhere)

    # test construction with `where` given by a function
    tag_list = [(1, 0), (1, 1), (1, 2)]

    def where(site):
        return site.tag in tag_list

    A = ops.Density(fsyst, where=where)
    assert all(fsyst.sites[A.where[w, 0]].tag in tag_list
               for w in range(A.where.shape[0]))

    where_list = set(kwant.HoppingKind((1, 0), lat)(syst))
    fwhere_list = set(
        (fsyst.id_by_site[a], fsyst.id_by_site[b]) for a, b in where_list)

    def where(a, b):
        return (a, b) in where_list

    A = ops.Current(fsyst, where=where)
    assert all((a, b) in fwhere_list for a, b in A.where)

    # test that `sum` is passed to constructors correctly
    for A in opservables:
        A(fsyst, sum=True).sum == True
Ejemplo n.º 17
0
"""An example of advanced system creation."""

from math import tanh
from cmath import exp
import tinyarray as ta
import kwant


sigma_0 = ta.identity(2)
sigma_x = ta.array([[0, 1], [1, 0]])
sigma_y = ta.array([[0, -1j], [1j, 0]])
sigma_z = ta.array([[1, 0], [0, -1]])


def make_system(R):
    def in_ring(pos):
        x, y = pos
        return R**2 / 4 < x**2 + y**2 < R**2

    def in_lead(pos):
        x, y = pos
        return -R / 4 < y < R / 4

    def pot(site, B):
        x, y = site.pos
        return (0.1 * tanh(x / R) + tanh(2 * y / R)) * sigma_z

    def hop(site1, site2, B):
        x1, y1 = site1.pos
        x2, y2 = site2.pos
        return - exp(.5j * B * (x1 - x2) * (y1 + y2)) * sigma_0
Ejemplo n.º 18
0
def test_finalization():
    """Test the finalization of finite and infinite systems.

    In order to exactly verify the finalization, low-level features of the
    build module are used directly.  This is not the way one would use a
    finalized system in normal code.
    """
    def set_sites(dest):
        while len(dest) < n_sites:
            site = rng.randrange(size), rng.randrange(size)
            if site not in dest:
                dest[site] = random_onsite_hamiltonian(rng)

    def set_hops(dest, sites):
        while len(dest) < n_hops:
            a, b = rng.sample(list(sites), 2)
            if (a, b) not in dest and (b, a) not in dest:
                dest[a, b] = random_hopping_integral(rng)

    rng = Random(123)
    size = 20
    n_sites = 120
    n_hops = 500

    # Make scattering region blueprint.
    sr_sites = {}
    set_sites(sr_sites)
    sr_hops = {}
    set_hops(sr_hops, sr_sites)

    # Make lead blueprint.
    possible_neighbors = rng.sample(list(sr_sites), n_sites // 2)
    lead_sites = {}
    for pn in possible_neighbors:
        lead_sites[pn] = random_hopping_integral(rng)
    set_sites(lead_sites)
    lead_hops = {}        # Hoppings within a single lead unit cell
    set_hops(lead_hops, lead_sites)
    lead_sites_list = list(lead_sites)
    neighbors = set()
    for i in range(n_hops):
        while True:
            a = rng.choice(lead_sites_list)
            b = rng.choice(possible_neighbors)
            neighbors.add(b)
            b = b[0] - size, b[1]
            if rng.randrange(2):
                a, b = b, a
            if (a, b) not in lead_hops and (b, a) not in lead_hops:
                break
        lead_hops[a, b] = random_hopping_integral(rng)
    neighbors = sorted(neighbors)

    # Build scattering region from blueprint and test it.
    syst = builder.Builder()
    fam = kwant.lattice.general(ta.identity(2))
    for site, value in sr_sites.items():
        syst[fam(*site)] = value
    for hop, value in sr_hops.items():
        syst[fam(*hop[0]), fam(*hop[1])] = value
    fsyst = syst.finalized()
    check_id_by_site(fsyst)
    check_onsite(fsyst, sr_sites)
    check_hoppings(fsyst, sr_hops)
    # check that sites are sorted
    assert fsyst.sites == tuple(sorted(fam(*site) for site in sr_sites))

    # Build lead from blueprint and test it.
    lead = builder.Builder(kwant.TranslationalSymmetry((size, 0)))
    for site, value in lead_sites.items():
        shift = rng.randrange(-5, 6) * size
        site = site[0] + shift, site[1]
        lead[fam(*site)] = value
    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter("always")
        lead.finalized()        # Trigger the warning.
        assert len(w) == 1
        assert issubclass(w[0].category, RuntimeWarning)
        assert "disconnected" in str(w[0].message)
    for (a, b), value in lead_hops.items():
        shift = rng.randrange(-5, 6) * size
        a = a[0] + shift, a[1]
        b = b[0] + shift, b[1]
        lead[fam(*a), fam(*b)] = value
    flead = lead.finalized()
    all_sites = list(lead_sites)
    all_sites.extend((x - size, y) for (x, y) in neighbors)
    check_id_by_site(fsyst)
    check_onsite(flead, all_sites, check_values=False)
    check_onsite(flead, lead_sites, subset=True)
    check_hoppings(flead, lead_hops)

    # Attach lead to system with empty interface.
    syst.leads.append(builder.BuilderLead(lead, ()))
    raises(ValueError, syst.finalized)

    # Attach lead with improper interface.
    syst.leads[-1] = builder.BuilderLead(
        lead, 2 * tuple(builder.Site(fam, n) for n in neighbors))
    raises(ValueError, syst.finalized)

    # Attach lead properly.
    syst.leads[-1] = builder.BuilderLead(
        lead, (builder.Site(fam, n) for n in neighbors))
    fsyst = syst.finalized()
    assert len(fsyst.lead_interfaces) == 1
    assert ([fsyst.sites[i].tag for i in fsyst.lead_interfaces[0]] ==
            neighbors)

    # test that we cannot finalize a system with a badly sorted interface order
    raises(ValueError, lead._finalized_infinite,
           [builder.Site(fam, n) for n in reversed(neighbors)])
    # site ordering independent of whether interface was specified
    flead_order = lead._finalized_infinite([builder.Site(fam, n)
                                            for n in neighbors])
    assert flead.sites == flead_order.sites


    syst.leads[-1] = builder.BuilderLead(
        lead, (builder.Site(fam, n) for n in neighbors))
    fsyst = syst.finalized()
    assert len(fsyst.lead_interfaces) == 1
    assert ([fsyst.sites[i].tag for i in fsyst.lead_interfaces[0]] ==
            neighbors)

    # Add a hopping to the lead which couples two next-nearest cells and check
    # whether this leads to an error.
    a = rng.choice(lead_sites_list)
    b = rng.choice(possible_neighbors)
    b = b[0] + 2 * size, b[1]
    lead[fam(*a), fam(*b)] = random_hopping_integral(rng)
    raises(ValueError, lead.finalized)
Ejemplo n.º 19
0
def test_fill():
    g = kwant.lattice.square()
    sym_x = kwant.TranslationalSymmetry((-1, 0))
    sym_xy = kwant.TranslationalSymmetry((-1, 0), (0, 1))

    template_1d = builder.Builder(sym_x)
    template_1d[g(0, 0)] = None
    template_1d[g.neighbors()] = None

    def line_200(site):
        return -100 <= site.pos[0] < 100

    ## Test that copying a builder by "fill" preserves everything.
    for sym, func in [
        (kwant.TranslationalSymmetry(*np.diag([3, 4, 5])), lambda pos: True),
        (builder.NoSymmetry(), lambda pos: ta.dot(pos, pos) < 17)
    ]:
        cubic = kwant.lattice.general(ta.identity(3))

        # Make a weird system.
        orig = kwant.Builder(sym)
        sites = cubic.shape(func, (0, 0, 0))
        for i, site in enumerate(orig.expand(sites)):
            if i % 7 == 0:
                continue
            orig[site] = i
        for i, hopp in enumerate(orig.expand(cubic.neighbors(1))):
            if i % 11 == 0:
                continue
            orig[hopp] = i * 1.2345
        for i, hopp in enumerate(orig.expand(cubic.neighbors(2))):
            if i % 13 == 0:
                continue
            orig[hopp] = i * 1j

        # Clone the original using fill.
        clone = kwant.Builder(sym)
        clone.fill(orig, lambda s: True, (0, 0, 0))

        # Verify that both are identical.
        assert set(clone.site_value_pairs()) == set(orig.site_value_pairs())
        assert (set(clone.hopping_value_pairs()) == set(
            orig.hopping_value_pairs()))

    ## Test for warning when "start" is out.
    target = builder.Builder()
    for start in [(-101, 0), (101, 0)]:
        with warns(RuntimeWarning):
            target.fill(template_1d, line_200, start)

    ## Test filling of infinite builder.
    for n in [1, 2, 4]:
        sym_n = kwant.TranslationalSymmetry((n, 0))
        for start in [g(0, 0), g(20, 0)]:
            target = builder.Builder(sym_n)
            sites = target.fill(template_1d,
                                lambda s: True,
                                start,
                                max_sites=10)
            assert len(sites) == n
            assert len(list(target.hoppings())) == n
            assert set(sym_n.to_fd(s) for s in sites) == set(target.sites())

    ## test max_sites
    target = builder.Builder()
    for max_sites in (-1, 0):
        with raises(ValueError):
            target.fill(template_1d,
                        lambda site: True,
                        g(0, 0),
                        max_sites=max_sites)
        assert len(list(target.sites())) == 0
    target = builder.Builder()
    with raises(RuntimeError):
        target.fill(template_1d, line_200, g(0, 0), max_sites=10)
    ## test filling
    target = builder.Builder()
    added_sites = target.fill(template_1d, line_200, g(0, 0))
    assert len(added_sites) == 200
    # raise warning if target already contains all starting sites
    with warns(RuntimeWarning):
        target.fill(template_1d, line_200, g(0, 0))

    ## test multiplying unit cell size in 1D
    n_cells = 10
    sym_nx = kwant.TranslationalSymmetry(*(sym_x.periods * n_cells))
    target = builder.Builder(sym_nx)
    target.fill(template_1d, lambda site: True, g(0, 0))

    should_be_syst = builder.Builder(sym_nx)
    should_be_syst[(g(i, 0) for i in range(n_cells))] = None
    should_be_syst[g.neighbors()] = None

    assert sorted(target.sites()) == sorted(should_be_syst.sites())
    assert sorted(target.hoppings()) == sorted(should_be_syst.hoppings())

    ## test multiplying unit cell size in 2D
    template_2d = builder.Builder(sym_xy)
    template_2d[g(0, 0)] = None
    template_2d[g.neighbors()] = None
    template_2d[builder.HoppingKind((2, 2), g)] = None

    nm_cells = (3, 5)
    sym_nmxy = kwant.TranslationalSymmetry(*(sym_xy.periods * nm_cells))
    target = builder.Builder(sym_nmxy)
    target.fill(template_2d, lambda site: True, g(0, 0))

    should_be_syst = builder.Builder(sym_nmxy)
    should_be_syst[(g(i, j) for i in range(10) for j in range(10))] = None
    should_be_syst[g.neighbors()] = None
    should_be_syst[builder.HoppingKind((2, 2), g)] = None

    assert sorted(target.sites()) == sorted(should_be_syst.sites())
    assert sorted(target.hoppings()) == sorted(should_be_syst.hoppings())

    ## test filling 0D builder with 2D builder
    def square_shape(site):
        x, y = site.tag
        return 0 <= x < 10 and 0 <= y < 10

    target = builder.Builder()
    target.fill(template_2d, square_shape, g(0, 0))

    should_be_syst = builder.Builder()
    should_be_syst[(g(i, j) for i in range(10) for j in range(10))] = None
    should_be_syst[g.neighbors()] = None
    should_be_syst[builder.HoppingKind((2, 2), g)] = None

    assert sorted(target.sites()) == sorted(should_be_syst.sites())
    assert sorted(target.hoppings()) == sorted(should_be_syst.hoppings())

    ## test that 'fill' respects the symmetry of the target builder
    lat = kwant.lattice.chain(a=1)
    template = builder.Builder(kwant.TranslationalSymmetry((-1, )))
    template[lat(0)] = 2
    template[lat.neighbors()] = -1

    target = builder.Builder(kwant.TranslationalSymmetry((-2, )))
    target[lat(0)] = None
    to_target_fd = target.symmetry.to_fd
    # Refuses to fill the target because target already contains the starting
    # site.
    with warns(RuntimeWarning):
        target.fill(template, lambda x: True, lat(0))

    # should only add a single site (and hopping)
    new_sites = target.fill(template, lambda x: True, lat(1))
    assert target[lat(0)] is None  # should not be overwritten by template
    assert target[lat(-1)] == template[lat(0)]
    assert len(new_sites) == 1
    assert to_target_fd(new_sites[0]) == to_target_fd(lat(-1))
Ejemplo n.º 20
0
def test_finalization():
    """Test the finalization of finite and infinite systems.

    In order to exactly verify the finalization, low-level features of the
    build module are used directly.  This is not the way one would use a
    finalized system in normal code.
    """
    def set_sites(dest):
        while len(dest) < n_sites:
            site = rng.randrange(size), rng.randrange(size)
            if site not in dest:
                dest[site] = random_onsite_hamiltonian(rng)

    def set_hops(dest, sites):
        while len(dest) < n_hops:
            a, b = rng.sample(list(sites), 2)
            if (a, b) not in dest and (b, a) not in dest:
                dest[a, b] = random_hopping_integral(rng)

    rng = Random(123)
    size = 20
    n_sites = 120
    n_hops = 500

    # Make scattering region blueprint.
    sr_sites = {}
    set_sites(sr_sites)
    sr_hops = {}
    set_hops(sr_hops, sr_sites)

    # Make lead blueprint.
    possible_neighbors = rng.sample(list(sr_sites), n_sites // 2)
    lead_sites = {}
    for pn in possible_neighbors:
        lead_sites[pn] = random_hopping_integral(rng)
    set_sites(lead_sites)
    lead_hops = {}  # Hoppings within a single lead unit cell
    set_hops(lead_hops, lead_sites)
    lead_sites_list = list(lead_sites)
    neighbors = set()
    for i in range(n_hops):
        while True:
            a = rng.choice(lead_sites_list)
            b = rng.choice(possible_neighbors)
            neighbors.add(b)
            b = b[0] - size, b[1]
            if rng.randrange(2):
                a, b = b, a
            if (a, b) not in lead_hops and (b, a) not in lead_hops:
                break
        lead_hops[a, b] = random_hopping_integral(rng)
    neighbors = sorted(neighbors)

    # Build scattering region from blueprint and test it.
    syst = builder.Builder()
    fam = kwant.lattice.general(ta.identity(2))
    for site, value in sr_sites.items():
        syst[fam(*site)] = value
    for hop, value in sr_hops.items():
        syst[fam(*hop[0]), fam(*hop[1])] = value
    fsyst = syst.finalized()
    check_id_by_site(fsyst)
    check_onsite(fsyst, sr_sites)
    check_hoppings(fsyst, sr_hops)
    # check that sites are sorted
    assert fsyst.sites == tuple(sorted(fam(*site) for site in sr_sites))

    # Build lead from blueprint and test it.
    lead = builder.Builder(kwant.TranslationalSymmetry((size, 0)))
    for site, value in lead_sites.items():
        shift = rng.randrange(-5, 6) * size
        site = site[0] + shift, site[1]
        lead[fam(*site)] = value
    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter("always")
        lead.finalized()  # Trigger the warning.
        assert len(w) == 1
        assert issubclass(w[0].category, RuntimeWarning)
        assert "disconnected" in str(w[0].message)
    for (a, b), value in lead_hops.items():
        shift = rng.randrange(-5, 6) * size
        a = a[0] + shift, a[1]
        b = b[0] + shift, b[1]
        lead[fam(*a), fam(*b)] = value
    flead = lead.finalized()
    all_sites = list(lead_sites)
    all_sites.extend((x - size, y) for (x, y) in neighbors)
    check_id_by_site(fsyst)
    check_onsite(flead, all_sites, check_values=False)
    check_onsite(flead, lead_sites, subset=True)
    check_hoppings(flead, lead_hops)

    # Attach lead to system with empty interface.
    syst.leads.append(builder.BuilderLead(lead, ()))
    raises(ValueError, syst.finalized)

    # Attach lead with improper interface.
    syst.leads[-1] = builder.BuilderLead(
        lead, 2 * tuple(builder.Site(fam, n) for n in neighbors))
    raises(ValueError, syst.finalized)

    # Attach lead properly.
    syst.leads[-1] = builder.BuilderLead(lead, (builder.Site(fam, n)
                                                for n in neighbors))
    fsyst = syst.finalized()
    assert len(fsyst.lead_interfaces) == 1
    assert ([fsyst.sites[i].tag
             for i in fsyst.lead_interfaces[0]] == neighbors)

    # test that we cannot finalize a system with a badly sorted interface order
    raises(ValueError, builder.InfiniteSystem, lead,
           [builder.Site(fam, n) for n in reversed(neighbors)])
    # site ordering independent of whether interface was specified
    flead_order = builder.InfiniteSystem(
        lead, [builder.Site(fam, n) for n in neighbors])
    assert flead.sites == flead_order.sites

    syst.leads[-1] = builder.BuilderLead(lead, (builder.Site(fam, n)
                                                for n in neighbors))
    fsyst = syst.finalized()
    assert len(fsyst.lead_interfaces) == 1
    assert ([fsyst.sites[i].tag
             for i in fsyst.lead_interfaces[0]] == neighbors)

    # Add a hopping to the lead which couples two next-nearest cells and check
    # whether this leads to an error.
    a = rng.choice(lead_sites_list)
    b = rng.choice(possible_neighbors)
    b = b[0] + 2 * size, b[1]
    lead[fam(*a), fam(*b)] = random_hopping_integral(rng)
    raises(ValueError, lead.finalized)
Ejemplo n.º 21
0
def test_opservables_construction():
    lat, syst = _random_square_system(3)
    fsyst = syst.finalized()
    N = len(fsyst.sites)

    # test construction failure if norbs not given
    latnone = kwant.lattice.chain()
    syst[latnone(0)] = 1
    for A in opservables:
        raises(ValueError, A, syst.finalized())
    del syst[latnone(0)]

    # test construction failure when dimensions of onsite do not match
    for A in opservables:
        raises(ValueError, A, fsyst, onsite=np.eye(2))

    # test that error is raised when input array is the wrong size
    for A in opservables:
        a = A(fsyst)
        kets = list(map(np.ones, [(0,), (N - 1,), (N + 1,), (N, 1)]))
        for ket in kets:
            raises(ValueError, a, ket)
            raises(ValueError, a, ket, ket)
            raises(ValueError, a.act, ket)
            raises(ValueError, a.act, ket, ket)

    # Test `check_hermiticity=False`
    for A in (ops.Density, ops.Current, ops.Source):
        raises(ValueError, A, fsyst, 1j)

    # test construction with different numbers of orbitals
    lat2 = kwant.lattice.chain(norbs=2)
    extra_sites = [lat2(i) for i in range(N)]
    syst[extra_sites] = np.eye(2)
    syst[zip(fsyst.sites, extra_sites)] = ta.matrix([1, 1])
    for A in opservables:
        raises(ValueError, A, syst.finalized(), onsite=np.eye(2))
        A(syst.finalized())
        A.onsite == np.eye(2)
    del syst[extra_sites]

    check = [(ops.Density, np.arange(N).reshape(-1, 1), ta.identity(1)),
             (ops.Current, np.array(list(fsyst.graph)), ta.identity(1)),
             (ops.Source, np.arange(N).reshape(-1, 1), ta.identity(1))]

    # test basic construction
    for A, where, onsite in check:
        a = A(fsyst)
        assert np.all(np.asarray(a.where) == where)
        assert all(a.onsite == onsite for i in range(N))

    # test construction with dict `onsite`
    for A in opservables:
        B = A(fsyst, {lat: 1})
        assert all(B.onsite(i) == 1 for i in range(N))

    # test construction with a functional onsite
    for A in opservables:
        B = A(fsyst, lambda site: site.pos[0])  # x-position operator
        assert all(B.onsite(i) == fsyst.sites[i].pos[0] for i in range(N))

    # test construction with `where` given by a sequence
    where = [lat(2, 2), lat(1, 1)]
    fwhere = tuple(fsyst.id_by_site[s] for s in where)
    A = ops.Density(fsyst, where=where)
    assert np.all(np.asarray(A.where).reshape(-1) == fwhere)

    where = [(lat(2, 2), lat(1, 2)), (lat(0, 0), lat(0, 1))]
    fwhere = np.asarray([(fsyst.id_by_site[a], fsyst.id_by_site[b])
              for a, b in where])
    A = ops.Current(fsyst, where=where)
    assert np.all(np.asarray(A.where) == fwhere)

    # test construction with `where` given by a function
    tag_list = [(1, 0), (1, 1), (1, 2)]
    def where(site):
        return site.tag in tag_list
    A = ops.Density(fsyst, where=where)
    assert all(fsyst.sites[A.where[w, 0]].tag in tag_list
               for w in range(A.where.shape[0]))

    where_list = set(kwant.HoppingKind((1, 0), lat)(syst))
    fwhere_list = set((fsyst.id_by_site[a], fsyst.id_by_site[b])
                      for a, b in where_list)
    def where(a, b):
        return (a, b) in where_list
    A = ops.Current(fsyst, where=where)
    assert all((a, b) in fwhere_list for a, b in A.where)
Ejemplo n.º 22
0
"""An example of advanced system creation."""

from math import tanh
from cmath import exp
import tinyarray as ta
import kwant

sigma_0 = ta.identity(2)
sigma_x = ta.array([[0, 1], [1, 0]])
sigma_y = ta.array([[0, -1j], [1j, 0]])
sigma_z = ta.array([[1, 0], [0, -1]])


def make_system(R):
    def in_ring(pos):
        x, y = pos
        return R**2 / 4 < x**2 + y**2 < R**2

    def in_lead(pos):
        x, y = pos
        return -R / 4 < y < R / 4

    def pot(site, B):
        x, y = site.pos
        return (0.1 * tanh(x / R) + tanh(2 * y / R)) * sigma_z

    def hop(site1, site2, B):
        x1, y1 = site1.pos
        x2, y2 = site2.pos
        return -exp(.5j * B * (x1 - x2) * (y1 + y2)) * sigma_0