Beispiel #1
0
def test_line():
    """1D shape with 1D lattice"""
    model = pb.Model(examples.chain_lattice(a=1), pb.line(0, 4.5))
    assert model.system.num_sites == 4

    model = pb.Model(examples.chain_lattice(a=1), pb.line([0, -0.5], [5, 0.5]))
    assert model.system.num_sites == 6
Beispiel #2
0
def test_hopping_generator():
    """Generated next-nearest hoppings should produce the same result as the builtin lattice"""
    from scipy.spatial import cKDTree

    @pb.hopping_generator("tnn_test", energy=graphene.t_nn)
    def next_nearest(x, y, z):
        pos = np.stack([x, y, z], axis=1)
        dmin = graphene.a * 0.95
        dmax = graphene.a * 1.05
        kdtree = cKDTree(pos)
        coo = kdtree.sparse_distance_matrix(kdtree, dmax).tocoo()
        idx = coo.data > dmin
        return coo.row[idx], coo.col[idx]

    @pb.onsite_energy_modifier
    def onsite_offset(energy):
        return energy + 3 * graphene.t_nn

    model = pb.Model(graphene.monolayer(), next_nearest, onsite_offset,
                     graphene.hexagon_ac(1))
    expected = pb.Model(graphene.monolayer(2), graphene.hexagon_ac(1))
    assert pytest.fuzzy_equal(model.hamiltonian, expected.hamiltonian)

    @pb.hopping_generator("t_new", energy=1.0)
    def bad_generator():
        """Different array lengths"""
        return [0, 1, 2], [0, 1]

    model = pb.Model(graphene.monolayer(), pb.primitive(3, 3), bad_generator)
    with pytest.raises(RuntimeError) as excinfo:
        model.eval()
    assert "the number of `from` and `to` indices must be equal" in str(
        excinfo.value)
Beispiel #3
0
def test_multiorbital_hamiltonian():
    """For multi-orbital lattices the Hamiltonian size is larger than the number of sites"""
    def lattice():
        lat = pb.Lattice([1])
        lat.add_sublattices(("A", [0], [[1, 3j], [0, 2]]))
        lat.register_hopping_energies({
            "t22": [[0, 1], [2, 3]],
            "t11":
            1,  # incompatible hopping - it's never used so it shouldn't raise any errors
        })
        lat.add_hoppings(([1], "A", "A", "t22"))
        return lat

    model = pb.Model(lattice(), pb.primitive(3))
    h = model.hamiltonian.toarray()

    assert model.system.num_sites == 3
    assert h.shape[0] == 6
    assert pytest.fuzzy_equal(h, h.T.conjugate())
    assert pytest.fuzzy_equal(h[:2, :2], h[-2:, -2:])
    assert pytest.fuzzy_equal(h[:2, :2], [[1, 3j], [-3j, 2]])
    assert pytest.fuzzy_equal(h[:2, 2:4], [[0, 1], [2, 3]])

    @pb.onsite_energy_modifier
    def onsite(energy, x, sub_id):
        return 3 * energy + sub_id.eye * 0 * x

    @pb.hopping_energy_modifier
    def hopping(energy):
        return 2 * energy

    model = pb.Model(lattice(), pb.primitive(3), onsite, hopping)
    h = model.hamiltonian.toarray()

    assert model.system.num_sites == 3
    assert h.shape[0] == 6
    assert pytest.fuzzy_equal(h, h.T.conjugate())
    assert pytest.fuzzy_equal(h[:2, :2], h[-2:, -2:])
    assert pytest.fuzzy_equal(h[:2, :2], [[3, 9j], [-9j, 6]])
    assert pytest.fuzzy_equal(h[:2, 2:4], [[0, 2], [4, 6]])
    assert pytest.fuzzy_equal(h[2:4, 4:6], [[0, 2], [4, 6]])

    def lattice_with_zero_diagonal():
        lat = pb.Lattice([1])
        lat.add_sublattices(("A", [0], [[0, 3j], [0, 0]]))
        return lat

    model = pb.Model(lattice_with_zero_diagonal(), pb.primitive(3))
    h = model.hamiltonian.toarray()

    assert model.system.num_sites == 3
    assert h.shape[0] == 6
    assert pytest.fuzzy_equal(h, h.T.conjugate())
    assert pytest.fuzzy_equal(h[:2, :2], h[-2:, -2:])
    assert pytest.fuzzy_equal(h[:2, :2], [[0, 3j], [-3j, 0]])
Beispiel #4
0
def test_primitive():
    """The primitive shape can be positioned using the lattice origin"""
    model = pb.Model(graphene.monolayer(), pb.primitive(2, 2))
    assert model.system.num_sites == 8
    assert np.isclose(model.system.x.min(), -1.5 * graphene.a, rtol=1e-3)
    assert np.isclose(model.system.y.min(), -2 * graphene.a_cc, rtol=1e-3)

    model = pb.Model(
        graphene.monolayer().with_offset(
            [0.5 * graphene.a, 0.5 * graphene.a_cc]), pb.primitive(2, 2))
    assert model.system.num_sites == 8
    assert np.isclose(model.system.x.min(), -graphene.a, rtol=1e-3)
    assert np.isclose(model.system.y.min(), -1.5 * graphene.a_cc, rtol=1e-3)
Beispiel #5
0
def test_hopping_buffer():
    """The energy passed to hopping modifiers is buffered, but users should not be aware of it"""
    def lattice():
        lat = pb.Lattice([1, 0], [0, 1])

        lat.add_sublattices(("A", [0, 0], [0, 0, 0, 0]))
        lat.register_hopping_energies({
            "t44": [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11],
                    [12, 13, 14, 15]]
        })
        lat.add_hoppings(([1, 0], "A", "A", "t44"), ([0, 1], "A", "A", "t44"))
        return lat

    capture = {}

    @pb.hopping_energy_modifier
    def check_buffer(energy, hop_id):
        capture.setdefault(hop_id, [])
        capture[hop_id] += [energy.copy()]
        energy[0] = 99
        return energy

    model = pb.Model(lattice(), pb.primitive(3000, 2), check_buffer)
    assert model.system.num_sites == 6000
    assert model.hamiltonian.shape[0] == 24000

    energies = capture["t44"]
    assert len(energies) >= 2
    assert energies[0].shape == (6250, 4, 4)
    for energy in energies:
        assert np.argwhere(energy == 99).size == 0
Beispiel #6
0
def test_structure_map_plot(compare_figure):
    model = pb.Model(graphene.monolayer(), pb.rectangle(0.8))
    structure_map = model.structure_map(model.system.x * model.system.y)

    with compare_figure() as chk:
        structure_map.plot(site_radius=(0.03, 0.05))
    assert chk.passed
Beispiel #7
0
def test_ldos_sublattice():
    """LDOS for A and B sublattices should be antisymmetric for graphene with a mass term"""
    model = pb.Model(graphene.monolayer(), graphene.hexagon_ac(10), graphene.mass_term(1))
    kpm = pb.chebyshev.kpm(model)

    a, b = (kpm.calc_ldos(np.linspace(-5, 5, 50), 0.1, [0, 0], sub) for sub in ('A', 'B'))
    assert pytest.fuzzy_equal(a.ldos, b.ldos[::-1], rtol=1e-3, atol=1e-6)
Beispiel #8
0
def test_complex_multiorbital_hamiltonian():
    def checkerboard_lattice(delta, t):
        lat = pb.Lattice(a1=[1, 0], a2=[0, 1])
        lat.add_sublattices(('A', [0, 0], -delta),
                            ('B', [1 / 2, 1 / 2], delta))
        lat.add_hoppings(
            ([0, 0], 'A', 'B', t),
            ([0, -1], 'A', 'B', t),
            ([-1, 0], 'A', 'B', t),
            ([-1, -1], 'A', 'B', t),
        )
        return lat

    hopp_t = np.array([[2 + 2j, 3 + 3j], [4 + 4j,
                                          5 + 5j]])  # multi-orbital hopping
    onsite_en = np.array([[1, 1j], [-1j, 1]])  # onsite energy

    model = pb.Model(checkerboard_lattice(onsite_en, hopp_t),
                     pb.translational_symmetry(True, True))
    h = model.hamiltonian.toarray()

    assert model.system.num_sites == 2
    assert h.shape[0] == 4
    assert pytest.fuzzy_equal(h, h.T.conjugate())  # check if Hermitian
    assert pytest.fuzzy_equal(
        h[:2, :2], -h[-2:, -2:])  # onsite energy on A and B is opposite
    assert pytest.fuzzy_equal(h[:2, 2:4],
                              4 * hopp_t)  # hopping A <-> B is 4 * hopp_t
Beispiel #9
0
def test_dos(params, baseline, plot_if_fails):
    configurations = [
        {
            'matrix_format': "ELL",
            'optimal_size': False,
            'interleaved': False
        },
        {
            'matrix_format': "ELL",
            'optimal_size': True,
            'interleaved': True
        },
    ]
    model = pb.Model(*params)

    kernel = pb.lorentz_kernel()
    strategies = [
        pb.kpm(model, kernel=kernel, silent=True, **c) for c in configurations
    ]

    energy = np.linspace(0, 2, 25)
    results = [kpm.calc_dos(energy, broadening=0.15) for kpm in strategies]

    expected = results[0].with_data(
        baseline(results[0].data.astype(np.float32)))
    for i in range(len(results)):
        plot_if_fails(results[i], expected, 'plot', label=i)

    for result in results:
        assert pytest.fuzzy_equal(result, expected, rtol=1e-3, atol=1e-6)
Beispiel #10
0
    def factory(v1, v2, energy=np.linspace(0, 0.1, 10)):
        model = pb.Model(graphene.monolayer(),
                         graphene.hexagon_ac(side_width=15),
                         pb.constant_potential(v1), pb.constant_potential(v2))

        kpm = pb.greens.kpm(model)
        return kpm.deferred_ldos(energy, broadening=0.15, position=[0, 0])
Beispiel #11
0
def test_api():
    model = pb.Model(graphene.monolayer(), pb.primitive(2, 2))
    system = model.system

    idx = system.num_sites // 2
    assert idx == system.find_nearest(system.xyz[idx])
    assert idx == system.find_nearest(system.xyz[idx], 'B')
    assert system.find_nearest([0, 0], 'A') != system.find_nearest([0, 0], 'B')

    with pytest.raises(IndexError) as excinfo:
        system.find_nearest([0, 0], 'invalid_sublattice')
    assert "There is no Site named" in str(excinfo.value)

    assert np.allclose(system.expanded_positions.x, system.positions.x)

    s = pb.Model(group6_tmd.monolayer_3band("MoS2"), pb.primitive(2, 2)).system
    assert s.expanded_positions.x.size == s.positions.x.size * 3
Beispiel #12
0
    def test_hamiltonian_submatrix_sites():
        """The `to_sites` and `from_sites` arguments are not supported"""
        kwant_sys = pb.Model(graphene.monolayer(), pb.rectangle(1,
                                                                1)).tokwant()

        with pytest.raises(RuntimeError) as excinfo:
            kwant_sys.hamiltonian_submatrix(to_sites=1, from_sites=1)
        assert "not supported" in str(excinfo.value)
Beispiel #13
0
 def test_warnings():
     """Extra arguments and ignored by pybinding -- warn users"""
     kwant_sys = pb.Model(graphene.monolayer(), pb.rectangle(1,
                                                             1)).tokwant()
     with pytest.warns(UserWarning):
         kwant_sys.hamiltonian_submatrix(sparse=True, args=(1, ))
     with pytest.warns(UserWarning):
         kwant_sys.hamiltonian_submatrix(sparse=True, params=dict(v=1))
Beispiel #14
0
def test_structure_map_plot(compare_figure):
    model = pb.Model(graphene.monolayer(), pb.rectangle(0.8))
    system = model.system
    data = np.arange(system.num_sites)
    structure_map = pb.results.StructureMap.from_system(data, system)

    with compare_figure() as chk:
        structure_map.plot_structure(site_radius=(0.03, 0.05), cbar_props=False)
    assert chk.passed
Beispiel #15
0
def test_structure_map_plot(compare_figure):
    model = pb.Model(graphene.monolayer(), pb.rectangle(0.8))
    data = [3, 11, 19, 26, 5, 13, 21, 0, 7, 15, 23, 2, 9, 17,
            10, 18, 25, 4, 12, 20, 27, 6, 14, 22, 1, 8, 16, 24]
    structure_map = model.structure_map(data)

    with compare_figure() as chk:
        structure_map.plot(site_radius=(0.03, 0.05))
    assert chk.passed
Beispiel #16
0
def test_sites():
    model = pb.Model(graphene.monolayer(), pb.primitive(2, 2))
    system = model.system

    sites = pb.system.Sites(system.positions, system.sublattices)
    idx = system.num_sites // 2
    assert idx == sites.find_nearest(system.xyz[idx])
    assert idx == sites.find_nearest(system.xyz[idx], system.sublattices[idx])
    assert sites.find_nearest([0, 0], 'A') != sites.find_nearest([0, 0], 'B')
Beispiel #17
0
def test_site_and_hopping_interaction():
    """Add a new row of sites and connect them just like the rest of the lattice"""
    d = 1.0
    v = 1.5
    t = 1.0

    def square_lattice():
        lat = pb.Lattice(a1=[d, 0], a2=[0, d])
        lat.add_sublattices(("A", [0, 0], v))
        lat.add_hoppings(([0, 1], "A", "A", t), ([1, 0], "A", "A", t))
        return lat

    @pb.site_generator(name="B", energy=v)
    def edge_sites(system):
        edge_atoms = system.count_neighbors() < 4
        x, y, z = (v[edge_atoms] for v in system.positions)

        top_edge_only = np.isclose(y, y.max())
        x, y, z = (v[top_edge_only] for v in (x, y, z))

        y += d
        return x, y, z

    @pb.hopping_generator(name="t_edge", energy=t)
    def edge_hoppings(system, y):
        new_sites = system.sub == "B"
        edge_atoms = np.logical_and(system.sub != "B",
                                    system.count_neighbors() < 4)
        top_edge_only = np.logical_and(edge_atoms,
                                       np.isclose(y, y[edge_atoms].max()))
        return new_sites, top_edge_only

    @pb.hopping_generator(name="t_edge2", energy=t)
    def edge_hoppings2(system):
        edge_idx = np.flatnonzero(system.sub == "B")
        to_idx = edge_idx[1:]
        from_idx = edge_idx[:-1]
        return to_idx, from_idx

    model = pb.Model(square_lattice(), pb.primitive(6, 4), edge_sites,
                     edge_hoppings, edge_hoppings2)
    expected = pb.Model(square_lattice(), pb.primitive(6, 5))
    assert pytest.fuzzy_equal(model.hamiltonian, expected.hamiltonian)
Beispiel #18
0
    def factory(v, energy=np.linspace(0, 0.1, 10)):
        model = pb.Model(graphene.monolayer(),
                         graphene.hexagon_ac(side_width=15),
                         pb.constant_potential(v))

        kpm = pb.kpm(model, kernel=pb.lorentz_kernel())
        return kpm.deferred_ldos(energy,
                                 broadening=0.15,
                                 position=[0, 0],
                                 sublattice="B")
Beispiel #19
0
def test_structure_map_plot(compare_figure):
    import matplotlib.pyplot as plt

    model = pb.Model(graphene.monolayer(), pb.rectangle(0.8))
    structure_map = model.structure_map(model.system.x * model.system.y)

    with compare_figure() as chk:
        structure_map.plot(site_radius=(0.03, 0.05))
        plt.gca().set_aspect("equal", "datalim")
    assert chk.passed
Beispiel #20
0
def test_optimized_hamiltonian():
    """Currently available only in internal interface"""
    from pybinding import _cpp
    model = pb.Model(graphene.monolayer(), graphene.hexagon_ac(10))
    h = model.hamiltonian
    oh = _cpp.OptimizedHamiltonian(model.raw_hamiltonian, 0)

    assert oh.matrix.shape == h.shape
    assert oh.sizes[-1] == h.shape[0]
    assert len(oh.indices) == h.shape[0]
Beispiel #21
0
def model():
    def ring(inner_radius, outer_radius):
        def contains(x, y, _):
            r = np.sqrt(x**2 + y**2)
            return np.logical_and(inner_radius < r, r < outer_radius)

        return pb.FreeformShape(contains,
                                width=[2 * outer_radius, 2 * outer_radius])

    return pb.Model(graphene.monolayer(), ring(3, 5))
Beispiel #22
0
 def make_model(v0=0):
     model = pb.Model(
         graphene.monolayer().with_min_neighbors(1),
         pb.rectangle(length, width),
         potential_barrier(v0),
     )
     model.attach_lead(
         -1, pb.line([-length / 2, -width / 2], [-length / 2, width / 2]))
     model.attach_lead(
         +1, pb.line([length / 2, -width / 2], [length / 2, width / 2]))
     return model
Beispiel #23
0
def square_model(width=2, height=3):
    def square_lattice(d=1, t=1):
        lat = pb.Lattice(a1=[d, 0], a2=[0, d])
        lat.add_sublattices(('A', [0, 0]))
        lat.add_hoppings(
            ([0, 1], 'A', 'A', -t),
            ([1, 0], 'A', 'A', -t),
        )
        return lat

    return pb.Model(square_lattice(), pb.rectangle(width, height))
Beispiel #24
0
def test_kpm_reuse():
    """KPM should return the same result when a single object is used for multiple calculations"""
    model = pb.Model(graphene.monolayer(), graphene.hexagon_ac(10))
    kpm = pb.chebyshev.kpm(model)
    energy = np.linspace(-5, 5, 50)
    broadening = 0.1

    for position in [0, 0], [6, 0]:
        actual = kpm.calc_ldos(energy, broadening, position)
        expected = pb.chebyshev.kpm(model).calc_ldos(energy, broadening, position)
        assert pytest.fuzzy_equal(actual, expected, rtol=1e-3, atol=1e-6)
Beispiel #25
0
def test_add_sublattice_alias(mock_lattice):
    c_position = [0, 9]
    mock_lattice.add_one_sublattice('c', c_position, alias='a')
    model = pb.Model(mock_lattice)
    c_index = model.system.find_nearest(c_position)

    assert mock_lattice['c'] != mock_lattice['a']
    assert model.system.sublattices[c_index] == mock_lattice['a']

    with pytest.raises(IndexError) as excinfo:
        mock_lattice.add_one_sublattice('d', [0, 0], alias='bad_name')
    assert "There is no sublattice named 'bad_name'" in str(excinfo.value)
Beispiel #26
0
def test_api():
    model = pb.Model(graphene.monolayer(), pb.primitive(2, 2))
    system = model.system

    idx = system.num_sites // 2
    assert idx == system.find_nearest(system.xyz[idx])
    assert idx == system.find_nearest(system.xyz[idx], 'B')
    assert system.find_nearest([0, 0], 'A') != system.find_nearest([0, 0], 'B')

    with pytest.raises(IndexError) as excinfo:
        system.find_nearest([0, 0], 'invalid_sublattice')
    assert "There is no sublattice" in str(excinfo.value)
Beispiel #27
0
def test_hopping_generator():
    """Generated next-nearest hoppings should produce the same result as the builtin lattice"""
    from scipy.spatial import cKDTree

    @pb.hopping_generator("tnn_test", energy=graphene.t_nn)
    def next_nearest(x, y, z):
        pos = np.stack([x, y, z], axis=1)
        dmin = graphene.a * 0.95
        dmax = graphene.a * 1.05
        kdtree = cKDTree(pos)
        coo = kdtree.sparse_distance_matrix(kdtree, dmax).tocoo()
        idx = coo.data > dmin
        return coo.row[idx], coo.col[idx]

    @pb.onsite_energy_modifier
    def onsite_offset(energy):
        return energy + 3 * graphene.t_nn

    model = pb.Model(graphene.monolayer(), next_nearest, onsite_offset, graphene.hexagon_ac(1))
    expected = pb.Model(graphene.monolayer(2), graphene.hexagon_ac(1))
    assert pytest.fuzzy_equal(model.hamiltonian, expected.hamiltonian)
Beispiel #28
0
    def test_hamiltonian_submatrix_orbitals(lattice, norb):
        """Return the number of orbitals at each site in addition to the Hamiltonian"""
        model = pb.Model(lattice, pb.rectangle(1, 1))
        kwant_sys = model.tokwant()

        matrix, to_norb, from_norb = kwant_sys.hamiltonian_submatrix(
            sparse=True, return_norb=True)
        assert matrix.shape == model.hamiltonian.shape
        assert to_norb.size == model.system.num_sites
        assert from_norb.size == model.system.num_sites
        assert np.all(to_norb == norb)
        assert np.all(from_norb == norb)
Beispiel #29
0
def test_multiorbital_onsite():
    def multi_orbital_lattice():
        lat = pb.Lattice([1, 0], [0, 1])

        tau_z = np.array([[1, 0],
                          [0, -1]])
        tau_x = np.array([[0, 1],
                          [1, 0]])
        lat.add_sublattices(("A", [0,   0], tau_z + 2 * tau_x),
                            ("B", [0, 0.1], 0.5),
                            ("C", [0, 0.2], [1, 2, 3]))
        lat.add_hoppings(([0, -1], "A", "A", 3 * tau_z),
                         ([1,  0], "A", "A", 3 * tau_z),
                         ([0, 0], "B", "C", [[2, 3, 4]]))
        return lat

    capture = {}

    @pb.onsite_energy_modifier
    def onsite(energy, x, y, z, sub_id):
        capture[sub_id] = [v.copy() for v in (energy, x, y, z)]
        return energy

    def assert_onsite(name, **expected):
        energy, x, y, z = capture[name]
        assert energy.shape == expected["shape"]

        expected_energy = np.array(expected["energy"])
        for index in np.ndindex(*expected_energy.shape):
            expected_slice = np.full(energy.shape[-1], expected_energy[index])
            assert pytest.fuzzy_equal(energy[index], expected_slice)

        assert pytest.fuzzy_equal(x, expected["x"])
        assert pytest.fuzzy_equal(y, expected["y"])
        assert pytest.fuzzy_equal(z, expected["z"])

    model = pb.Model(multi_orbital_lattice(), pb.rectangle(2, 1), onsite)
    assert model.system.num_sites == 6
    assert model.hamiltonian.shape[0] == 12

    assert_onsite("A", shape=(2, 2, 2), energy=[[1, 2],
                                                [2, -1]],
                  x=[0, 1], y=[0, 0], z=[0, 0])

    assert_onsite("B", shape=(2,), energy=[0.5],
                  x=[0, 1], y=[0.1, 0.1], z=[0, 0])

    assert_onsite("C", shape=(3, 3, 2), energy=[[1, 0, 0],
                                                [0, 2, 0],
                                                [0, 0, 3]],
                  x=[0, 1], y=[0.2, 0.2], z=[0, 0])
Beispiel #30
0
def test_api(ring_model):
    with pytest.raises(RuntimeError) as excinfo:
        ring_model.attach_lead(0, pb.line(0, 0))
    assert "Lead direction must be one of" in str(excinfo.value)

    for direction in [3, -3]:
        with pytest.raises(RuntimeError) as excinfo:
            ring_model.attach_lead(direction, pb.line(0, 0))
        assert "not valid for a 2D lattice" in str(excinfo.value)

    with pytest.raises(RuntimeError) as excinfo:
        pb.Model(examples.chain_lattice()).attach_lead(2, pb.line(0, 0))
    assert "Attaching leads to 1D lattices is not supported" in str(
        excinfo.value)