def test_attach(): """Attach 2 leads to a square lattice system""" w, h = 2, 3 model = square_model(w, h) model.attach_lead(-1, pb.line([0, -h / 2], [0, h / 2])) model.attach_lead(+1, pb.line([0, -h / 2], [0, h / 2])) assert len(model.leads) == 2 assert np.all(model.leads[0].indices == [0, 2, 4]) assert np.all(model.leads[1].indices == [1, 3, 5]) # Linear hopping grows from lead 0 to system to lead 1 model.add(linear_hopping()) assert model.leads[0].h1.data.max() < model.hamiltonian.data.min() assert model.hamiltonian.data.max() < model.leads[1].h1.data.min() # With the linear hopping modifier, the h1 hoppings should be equal to the # x position between the lead and main system x_mid_0 = (model.system.x.min() + model.leads[0].system.x.max()) / 2 assert np.allclose(model.leads[0].h1.data, x_mid_0) x_mid_1 = (model.system.x.max() + model.leads[1].system.x.min()) / 2 assert np.allclose(model.leads[1].h1.data, x_mid_1) # Linear onsite potential grows from lead 0 to system to lead 1 model.add(linear_onsite()) assert model.leads[0].h0.diagonal().max() < model.hamiltonian.diagonal( ).min() assert model.hamiltonian.diagonal().max() < model.leads[1].h0.diagonal( ).min()
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
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
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)
def pb_model(v=0, length=2, width=10): def square_lattice(d, t): lat = pb.Lattice(a1=[d, 0], a2=[0, d]) lat.add_sublattices(("A", [0, 0], 4 * t)) lat.add_hoppings(([0, 1], "A", "A", -t), ([1, 0], "A", "A", -t)) return lat @pb.onsite_energy_modifier def potential_well(energy, x): energy[np.logical_and(x >= 0, x <= 1)] -= v return energy model = pb.Model(square_lattice(d=1, t=1), pb.rectangle(length, width), potential_well) model.attach_lead(-1, pb.line([0, -width / 2 - 0.1], [0, width / 2])) model.attach_lead(+1, pb.line([0, -width / 2 - 0.1], [0, width / 2])) return model
def test_empty(ring_model): with pytest.raises(RuntimeError) as excinfo: ring_model.attach_lead(2, pb.line(0, 0)) assert ring_model.system assert "no sites in lead junction" in str(excinfo.value)
def test_complete_miss(ring_model): with pytest.raises(RuntimeError) as excinfo: ring_model.attach_lead(2, pb.line([4, -5], [5, -5])) assert ring_model.system assert "completely misses main structure" in str(excinfo.value)
def pb_model(v=0, length=2, width=10): model = pb.Model(square_lattice(d=1, t=1), pb.rectangle(x=length, y=width), potential_well(v)) model.attach_lead(-1, pb.line([0, -width / 2 - 0.1], [0, width / 2])) model.attach_lead(+1, pb.line([0, -width / 2 - 0.1], [0, width / 2])) return model
import matplotlib.pyplot as plt pb.pltutils.use_style() def simple_chain_lattice(a=1, t=-1): """Very simple 1D lattice""" lat = pb.Lattice(a) lat.add_one_sublattice('A', [0, 0]) lat.add_one_hopping(1, 'A', 'A', t) return lat model = pb.Model( simple_chain_lattice(), pb.line(-3.5, 3.5) # line start/end in nanometers ) model.plot() plt.show() def trestle(a=0.2, t1=0.8 + 0.6j, t2=2): """A more complicated 1D lattice with 2 sublattices""" lat = pb.Lattice(1.3 * a) lat.add_sublattices(('A', [0, 0], 0), ('B', [a / 2, a], 0)) lat.add_hoppings((0, 'A', 'B', t1), (1, 'A', 'B', t1), (1, 'A', 'A', t2), (1, 'B', 'B', t2)) lat.min_neighbors = 2 return lat