[email protected] wrote:
> I saw some users mentioning Hall effect computations on the community,
> such as the program 'qhe.py'. But I couldn't find related code or
> tutorials.
Hi, the program qhe.py is an example from the Kwant paper:
https://kwant-project.org/doc/. You can find the source code in the
paper, but I attach a newer version (that uses params instead of args).
This should be enough to experiment with QHE. Note that the shown
technique works only for constant field and all leads parallel to each
other. If you need something more generic, see
https://kwant-project.org/doc/1/pre/whatsnew/1.4#automatic-peierls-phase-calculation.
If all you need are non-parallel leads withconstant field, a manual
approach that uses a clever gauge transformation is also possible.
I attach a quick-and-dirty example.
Cheers
Christoph
import math
from cmath import exp
import numpy
from matplotlib import pyplot
import kwant
from kwant.digest import gauss
def hopping(sitei, sitej, phi):
xi, yi = sitei.pos
xj, yj = sitej.pos
return -exp(-0.5j * phi * (xi - xj) * (yi + yj))
def onsite(site, salt):
return 0.05 * gauss(repr(site), salt) + 4
def make_system(L=50):
def central_region(pos):
x, y = pos
return (-L < x < L
and abs(y) < L - 37.5 * math.exp(-x**2 / 12**2))
lat = kwant.lattice.square()
sys = kwant.Builder()
sys[lat.shape(central_region, (0, 0))] = onsite
sys[lat.neighbors()] = hopping
sym = kwant.TranslationalSymmetry((-1, 0))
lead = kwant.Builder(sym)
lead[(lat(0, y) for y in range(-L + 1, L))] = 4
lead[lat.neighbors()] = hopping
sys.attach_lead(lead)
sys.attach_lead(lead.reversed())
return sys.finalized()
sys = make_system()
energy = 0.15
# # Calculate and plot QHE conductance plateaus.
# reciprocal_phis = numpy.linspace(4, 50, 50)
# conductances = []
# for phi in 1 / reciprocal_phis:
# smatrix = kwant.smatrix(sys, energy, params=dict(phi=phi, salt=""))
# conductances.append(smatrix.transmission(1, 0))
# pyplot.plot(reciprocal_phis, conductances)
# pyplot.show()
# Calculate and plot a QHE edge state.
def density(sys, energy, params, lead_nr):
wf = kwant.wave_function(sys, energy, params=params)
return (abs(wf(lead_nr))**2).sum(axis=0)
d = density(sys, energy, dict(phi=1/40, salt=""), 0)
kwant.plotter.map(sys, d)
from cmath import exp
import kwant, numpy
from matplotlib import pyplot
lat = kwant.lattice.square()
def phase_x(a, b, B):
ap = a.pos
bp = b.pos
phase = -B * (0.5 * (ap[1] + bp[1]) * (bp[0] - ap[0]))
return -exp(1j * phase)
def gauge_x_to_y(s):
return numpy.prod(s.pos)
def phase_y(a, b, B):
ap = a.pos
bp = b.pos
phase = -B * (0.5 * (ap[1] + bp[1]) * (bp[0] - ap[0])
+ gauge_x_to_y(a) - gauge_x_to_y(b))
return -exp(1j * phase)
def gauge_scatreg(s):
return gauge_x_to_y(s) if s in gauge_transformed_sites else 0
def phase_scatreg(a, b, B):
ap = a.pos
bp = b.pos
phase = -B * (0.5 * (ap[1] + bp[1]) * (bp[0] - ap[0])
+ gauge_scatreg(a) - gauge_scatreg(b))
return -exp(1j * phase)
def make_lead(direction, width, r0, phase):
lead = kwant.Builder(kwant.TranslationalSymmetry(lat.vec(direction)))
lead[( lat(r0[0] - i * direction[1], r0[1] + i * direction[0])
for i in range(width) )] = 4
lead[lat.neighbors()] = phase
return lead
def main(E=1):
global gauge_transformed_sites
sys = kwant.Builder()
sys[( lat(x,y) for x in range(40) for y in range(40)
if y > 19 - abs(x-17) )] = 4
sys[lat.neighbors()] = phase_scatreg
sys.attach_lead(make_lead((1, 0), 18, (50, 0), phase_x))
sys.attach_lead(make_lead((-1, 0), 20, (50, 23), phase_x))
sys.attach_lead(make_lead((0, 1), 18, (19, 0), phase_y))
kwant.plot(sys)
sys = sys.finalized()
gauge_transformed_sites = set(sys.sites[i] for i in sys.lead_interfaces[2])
Bs = numpy.arange(-0.21, 0.5, 0.01)
conds = []
for B in Bs:
cond = kwant.smatrix(sys, E, args=[B]).transmission(1, 0)
conds.append(cond)
print(B, cond)
ax = pyplot.figure().add_subplot(1, 1, 1)
ax.plot(Bs, conds)
pyplot.show()
if __name__ == '__main__':
main()