
I know that the band diagram for the SSH can be easily obtained analytically, but I was wondering how one would go about it using kwant. If I understand correctly we require a translational symmetry such as to have an infinite lattice, so I defined a lead and tried to get the band structure from there. Unfortunately my code does not work and stops with a TypeError: Expecting an instance of SiteFamily. I thought that I implemented the hopping similar to the one from the graphene tutorial. Furthermore, I am wondering whether the definition of the lattice correct actually? To me it seems that the lattice vector [1,0] leaves us on the site of the b-sublattice. If I change it to [2,0] however I get a commensurate error The code that I have so far is below. Thank you, Steffen import numpy as np import kwant t = 1 SSH = kwant.lattice.general([[1, 0]], # lattice vectors [[0,0], [1,0]]) # Coordinates of the sites) a,b = SSH.sublattices SSH_lead = kwant.Builder(kwant.TranslationalSymmetry([-1, 0])) SSH_lead[a.shape((lambda pos: abs(pos[0]) == 0), (0, 0))] = 1 SSH_lead[b.shape((lambda pos: abs(pos[0]) == 1), (0, 0))] = 1 LongBond = (((1, 0), a, b)) ShortBond = (((-1, 0), a, b)) SSH_lead[[kwant.builder.HoppingKind(*hopping) for hopping in LongBond]] = 2 SSH_lead[[kwant.builder.HoppingKind(*hopping) for hopping in ShortBond]] = 1 kwant.plot(SSH_lead) kwant.plotter.bands(SSH_lead.finalized())

Hi Steffen. Your code fails in the following lines:
LongBond = (((1, 0), a, b)) SSH_lead[[kwant.builder.HoppingKind(*hopping) for hopping in LongBond]] = 2
because the 'LongBond' variable is not instantiated correctly. In Python you have to leave a trailing comma when creating a single-element tuple:
LongBond = (((1, 0), a, b),)
to make things easier to read you can also just create a list:
LongBond = [((1, 0), a, b)]
In the future you can try inserting calls to 'print' into your code to check certain conditions and inspect what is going on. Happy Kwanting, Joe

Hi Joe, thank you for your help (and also for getting back to a python and not a kwant one). The next error where it hangs 'Matrices are not aligned' are again inherently python, but I think the reason for the error is rooted in my layout of the 1D lattice. If I want a 1D lattice with a bi-atomic unit cell, is the following a correct way of defining the lattice? I am wondering, because I originally wanted to define my lattice vectors as [2,0] in order to not land on my second site when constructing the lattice, but it didn't let me (commensurate error). SSH = kwant.lattice.general([[1, 0]], # lattice vectors [[0,0], [1,0]]) # Coordinates of the sites) and sequentially when i want to define the short/long hoppings as (((0,0),a,b) and (((-1,0),a,b)? When the hoppings were defined in the graphene tutorial they also included the hopping like ((0,0),a,b) - does this refer to a hopping inside the unit cell itself between the two sublattices, I would have initially gone like (((1,0),a,b)? If you could shed some light on whats going on here with the sublattices or where I can read about it, that would be great. Thank you, Steffen ----------------------- complete code import numpy as np import kwant t = 1 SSH = kwant.lattice.general([[1, 0]], # lattice vectors [[0,0], [1,0]]) # Coordinates of the sites) a,b = SSH.sublattices SSH_lead = kwant.Builder(kwant.TranslationalSymmetry([-1, 0])) SSH_lead[a.shape((lambda pos: abs(pos[0]) == 0), (0, 0))] = 1 SSH_lead[b.shape((lambda pos: abs(pos[0]) == 1), (0, 0))] = 1 LongBond = [((0, 0), a, b),] ShortBond = [((-1, 0), a, b),] SSH_lead[[kwant.builder.HoppingKind(*hopping) for hopping in LongBond]] = 2 SSH_lead[[kwant.builder.HoppingKind(*hopping) for hopping in ShortBond]] = 1 kwant.plot(SSH_lead) kwant.plotter.bands(SSH_lead.finalized()) On 07/10/2017 06:36 AM, Joseph Weston wrote:
Hi Steffen.
Your code fails in the following lines:
LongBond = (((1, 0), a, b)) SSH_lead[[kwant.builder.HoppingKind(*hopping) for hopping in LongBond]] = 2
because the 'LongBond' variable is not instantiated correctly. In Python you have to leave a trailing comma when creating a single-element tuple:
LongBond = (((1, 0), a, b),) to make things easier to read you can also just create a list:
LongBond = [((1, 0), a, b)]
In the future you can try inserting calls to 'print' into your code to check certain conditions and inspect what is going on.
Happy Kwanting,
Joe

Hi Steffen,
If I want a 1D lattice with a bi-atomic unit cell, is the following a correct way of defining the lattice? I am wondering, because I originally wanted to define my lattice vectors as [2,0] in order to not land on my second site when constructing the lattice, but it didn't let me (commensurate error).
When creating a polyatomic lattice Kwant doesn't care where you put the sites of the lattice basis, so putting a site at (0, 0) and one at (1, 0) with a lattice vector of (1, 0) is perfectly valid; the sites will belong to different site families, so Kwant will not confuse the two. It will, however, be confusing for *you* when plotting, as site 'a(1)' will be at the same realspace position as site 'b(0)'. If you use (0, 0) and (1, 0) for your basis, and have a lattice vector of (2, 0), then the translational symmetry vector must also be (-2, 0) in order to be commensurate with the symmetry of the lattice. You could also choose a basis of (0, 0) and (0.5, 0) and keep the translational symmetry vector as (-1, 0).
The next error where it hangs 'Matrices are not aligned' are again inherently python, but I think the reason for the error is rooted in my layout of the 1D lattice.
The error occurs when trying to use the HoppingKind with: ((0, 0), a, b) The problem is actually that you have supplied the 'delta' argument as a tuple with 2 elements, whereas your site families (sublattices) are 1D, and therefore only require a tuple with a single element. You should therefore define your long and short hoppings like:
LongBond = [((0,), a, b)] ShortBond = [((-1,), a, b)]
When the hoppings were defined in the graphene tutorial they also included the hopping like ((0,0),a,b) - does this refer to a hopping inside the unit cell itself between the two sublattices, I would have initially gone like (((1,0),a,b)?
This question is related to the above; the documentation of HoppingKind explains this. The 'delta' argument to HoppingKind specifies the difference between the tags, i.e. 'HoppingKind(delta, a, b)' matches hoppings of the form '(a(x + delta), b(x))' where 'x' is any tag and '+' should be taken to mean vector addition (and not to mean "append", which is the Python semantics for '+' with lists and tuples -- 'delta' is internally converted into an array first). We can therefore see that providing '((0,), a, b)' means '(a(0), b(0))', '(a(1), b(1))' and so on. In the context of your example this means hoppings between the two sublattices in the same unit cell. '((1,), a, b)' means '(a(1), b(0))', '(a(2), b(1))' and so on, so in your example this is hoppings between different sublattices in neighboring unit cells. This should hopefully also explain why providing '((0, 0), a, b)' (i.e. with a 2-element 'delta') did not work; the shape is not compatible with the tag of the 'a' and 'b' lattices. The error message is pretty poor in this case, and can be improved. I have opened an issue [1] on the Kwant bug tracker about this. Thanks for helping us make Kwant better! Happy Kwanting, Joe [1]: https://gitlab.kwant-project.org/kwant/kwant/issues/147

Hi Joe, thank you very much for your extensive explanation - that definitely helped. I am getting the expected band-structure now and am attaching in case someone runs into the same problem. Thank you, Steffen import numpy as np import kwant import matplotlib.pyplot as plt SSH = kwant.lattice.general([[2, 0]], # lattice vectors [[0,0], [1,0]]) # Coordinates of the sites) a,b = SSH.sublattices SSH_lead = kwant.Builder(kwant.TranslationalSymmetry([-2, 0])) SSH_lead[a.shape((lambda pos: abs(pos[0]) == 0), (0, 0))] = 1 SSH_lead[b.shape((lambda pos: abs(pos[0]) == 1), (0, 0))] = 1 LongBond = [((0,), a, b)] ShortBond = [((-1,), a, b)] SSH_lead[[kwant.builder.HoppingKind(*hopping) for hopping in LongBond]] = 2 SSH_lead[[kwant.builder.HoppingKind(*hopping) for hopping in ShortBond]] = 1 kwant.plot(SSH_lead) kwant.plotter.bands(SSH_lead.finalized()) On 7/10/2017 9:48 AM, Joseph Weston wrote: > Hi Steffen, > > >> If I want a 1D lattice with a bi-atomic unit cell, is the following a >> correct way of defining the lattice? I am wondering, because I >> originally wanted to define my lattice vectors as [2,0] in order to >> not land on my second site when constructing the lattice, but it >> didn't let me (commensurate error). > When creating a polyatomic lattice Kwant doesn't care where you put the > sites of the lattice basis, so putting a site at (0, 0) and one at (1, > 0) with a lattice vector of (1, 0) is perfectly valid; the sites will > belong to different site families, so Kwant will not confuse the two. It > will, however, be confusing for *you* when plotting, as site 'a(1)' will > be at the same realspace position as site 'b(0)'. > > If you use (0, 0) and (1, 0) for your basis, and have a lattice vector > of (2, 0), then the translational symmetry vector must also be (-2, 0) > in order to be commensurate with the symmetry of the lattice. You could > also choose a basis of (0, 0) and (0.5, 0) and keep the translational > symmetry vector as (-1, 0). > > >> The next error where it hangs 'Matrices are not aligned' are again >> inherently python, but I think the reason for the error is rooted in >> my layout of the 1D lattice. > The error occurs when trying to use the HoppingKind with: > > ((0, 0), a, b) > > The problem is actually that you have supplied the 'delta' argument as a > tuple with 2 elements, whereas your site families (sublattices) are 1D, > and therefore only require a tuple with a single element. You should > therefore define your long and short hoppings like: > >> LongBond = [((0,), a, b)] >> ShortBond = [((-1,), a, b)] > >> When the hoppings were defined in the graphene tutorial they also >> included the hopping like ((0,0),a,b) - does this refer to a hopping >> inside the unit cell itself between the two sublattices, I would have >> initially gone like (((1,0),a,b)? > This question is related to the above; the documentation of HoppingKind > explains this. The 'delta' argument to HoppingKind specifies the > difference between the tags, i.e. 'HoppingKind(delta, a, b)' matches > hoppings of the form '(a(x + delta), b(x))' where 'x' is any tag and '+' > should be taken to mean vector addition (and not to mean "append", which > is the Python semantics for '+' with lists and tuples -- 'delta' is > internally converted into an array first). > > We can therefore see that providing '((0,), a, b)' means '(a(0), b(0))', > '(a(1), b(1))' and so on. In the context of your example this means > hoppings between the two sublattices in the same unit cell. '((1,), a, > b)' means '(a(1), b(0))', '(a(2), b(1))' and so on, so in your example > this is hoppings between different sublattices in neighboring unit cells. > > This should hopefully also explain why providing '((0, 0), a, b)' (i.e. > with a 2-element 'delta') did not work; the shape is not compatible with > the tag of the 'a' and 'b' lattices. > > The error message is pretty poor in this case, and can be improved. I > have opened an issue [1] on the Kwant bug tracker about this. Thanks for > helping us make Kwant better! > > Happy Kwanting, > > Joe > > [1]: https://gitlab.kwant-project.org/kwant/kwant/issues/147 >
participants (2)
-
Joseph Weston
-
Steffen Wittek