Hi Christoph,
Here is my code.
I did all as you described, you may try to run it yourself. Must take
around a minute.
Best wishes,
Sergey
On 25/09/2020 10:51, Christoph Groth wrote:
Sergey,
I’m a bit puzzled by the fact that your profile contains traces of
Cython cdef functions. They shouldn’t be visible to the Cython
profiler. Would you mind sharing the script that you profiled (or
something equivalent, but then with another profile)?
Cheers
Christoph
### Graphene ballistic edge-state field-effect transistor
from __future__ import division # so that 1/2 == 0.5, and not 0
import math
import numpy as np
from numpy import pi, sqrt, tanh, log, sin, cos, exp
import os
#import functools as ft
import itertools as it
from matplotlib import pyplot as plt
#from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import scipy.sparse as sparse
import scipy.sparse.linalg as sla
import kwant
#import random
from kwant.digest import gauss
#from colormaps import cmaps
from joblib import Parallel, delayed
path=os.getcwd()
sin_30, cos_30 = (1 / 2, sqrt(3) / 2)
lat = kwant.lattice.general([(1, 0, 0), (sin_30,cos_30, 0), (0,0, 2)],
[(0, 0, 0), (0,1 / sqrt(3), 0), (0, 0, 1), (1 /(2), 1/(2*sqrt(3)), 1)],name=('a','b','c','d'))
## to make it more clear, I tilt the layers, preserving the same hoppings. Now, g1 will look skew
#lat = kwant.lattice.general([(0, 1, 0), (cos_30, sin_30, 0), (0, 0, 1)],
# [(0, 0, 0), (1 / sqrt(3), 0, 0)],name=('a','b','d','c'))
fakelat= kwant.lattice.Monatomic([(1, 0, 0), (sin_30,cos_30, 0), (0,0, 2)], [0,0,0.1])
sys = kwant.Builder()
# types of sublattices - these are extracted by .family method: '0' and '1'
a, b, c, d = lat.sublattices
#delta=0
#g2=0
#g3=0
#g4=0
def Dot2(list1,list2):
return list1[0]*list2[0]+list1[1]*list2[1]
def g0hopping(sitei, sitej, peirels):
xi, yi, zi = sitei.pos
xj, yj ,zj= sitej.pos
return -g0 * peirels(sitei,sitej)
def g3hopping(sitei, sitej, peirels):
xi, yi, zi = sitei.pos
xj, yj ,zj= sitej.pos
return -g3 * peirels(sitei,sitej)
def g4hopping(sitei, sitej, peirels):
xi, yi, zi = sitei.pos
xj, yj ,zj= sitej.pos
return g4 * peirels(sitei,sitej)
def addt(tuple1,tuple2):
''' adds the two tuples '''
return tuple(map(lambda x, y: x + y, tuple1, tuple2))
def Eigensystem(bands,k):
mat = bands.hop * complex(math.cos(k), -math.sin(k))
mat += mat.conjugate().transpose() + bands.ham
ev,es = np.linalg.eigh(mat)
sortorder=np.argsort(np.absolute(ev))
return (ev[sortorder], es[:,sortorder])
def plot_wavefunction2D(flead, k, nvector=1,args=''):
"""nvector numbering is from 1 """
bands = kwant.physics.Bands(flead,args=args)
eval, evect = Eigensystem(bands,k)
evecs=evect[:,nvector-1]
wavefunction=np.absolute(evecs)
# xcoords = np.array([list(site.pos)[0] for site in flead.sites])[0:flead.cell_size]
ycoords = np.array([list(site.pos)[1] for site in flead.sites])[0:flead.cell_size]
# print xcoords, ycoords, zcoords
fig = plt.figure()
# ax = fig.add_subplot(1, 1, 1, projection='3d')
# The triangles in parameter space determine which x, y, z points are
# connected by an edge
plt.scatter(ycoords, wavefunction) #, triangles=tri.triangles, cmap=plt.cm.Spectral)
# print len(flead.sites)
# print xcoords, xcoords.shape
# plt.figure()
# print disorderWidth
# plt.scatter(xcoords,wavefunction)
plt.xlabel("y (lattice cells)")
plt.title("Mode Energy="+str(eval[nvector-1]))
eps=0.001
def TipPotential(sitei, depth, width,gate):
x, y, z=sitei.pos
if (sitei.family==a) or (sitei.family==c):
ad=DeltaAB+g2-Ef
else:
ad = g2-Ef
if z==0:
return depth*exp(-((x-shift)**2+y*y)/(2*width*width)) + ad
else:
if z==2:
return gate + ad
else:
return gate/3 + ad +U2/1000.0 + depth*exp(-((x-shift)**2+y*y)/(2*width*width))/3
def LeadPot(sitei, gate):
x, y, z=sitei.pos
if (sitei.family==a) or (sitei.family==c):
ad=DeltaAB+g2-Ef
else:
ad = g2-Ef
if z==0:
return ad
else:
if z==2:
return gate + ad
else:
return gate/3 + ad
def make_system(size: 50):
def connect(sys, crit):
for site1, site2 in it.product(sys.sites(), repeat=2):
if crit(site1, site2):
yield (site1, site2)
# kinds = [kwant.builder.HoppingKind(v, sublat) for v in [(1, 0), (0, 1),(-1,0),(0,-1),(1,-1),(-1,1)] for sublat in [a,b]]
# sys[kinds] = nexthoppingbulk
def critInterlayer(site1, site2): ## gamma1 hopping integral
diff = site1.pos - site2.pos
[x, y] = diff
if (0.01 < abs(x) + abs(y) < 0.1): # and (site1.tag!=site2.tag):
return True
else:
return False
## armchair stripe
sys = kwant.Builder()
def sys_region(pos):
x, y, z = pos
return (x * x + y * y <= size*size) and (0 <= z <= Nl-1)
sys[lat.shape(sys_region, (0, 0,0))] = TipPotential
hopping0 = (((0, 0,0), a, b), ((0, 1,0), a, b), ((-1, 1,0), a, b), ((0, 0,0), d, c),((0, -1,0), d, c),((-1, 0,0), d, c))
hoppingg1 = (((0, 0, 0), a, c),((0, 0, 1), a, c))
hoppingg4 = (((0, 0, 0), b, c),((0, 0, 1), b, c), ((1, -1, 0), b, c),((1, -1, 1), b, c), ((0, -1, 0), b, c), ((0, -1, 1), b, c),
((0, 0, 0), a, d),((0, 0, 1), a, d), ((1, 0, 0), a, d),((1, 0, 1), a, d), ((0, 1, 0), a, d), ((0, 1, 1), a, d))
hoppingg3 = (((0, 0, 0), b, d),((0, 0, 1), b, d), ((1, 0, 0), b, d),((1, 0, 1), b, d), ((1, -1, 0), b, d),((1, -1, 1), b, d))
hoppingg2 = (((0, 0, 1), b, b),((0, 0, 1), d, d))
hoppingg5 = (((0, 0, 1), c, c), ((0, 0, 1), a, a))
print("setting hoppings")
sys[[kwant.builder.HoppingKind(*hopping) for hopping in hopping0]] = g0hopping
sys[[kwant.builder.HoppingKind(*hopping) for hopping in hoppingg1]] = g1
sys[[kwant.builder.HoppingKind(*hopping) for hopping in hoppingg4]] = g4hopping
sys[[kwant.builder.HoppingKind(*hopping) for hopping in hoppingg3]] = g3hopping
sys[[kwant.builder.HoppingKind(*hopping) for hopping in hoppingg2]] = g2/2
sys[[kwant.builder.HoppingKind(*hopping) for hopping in hoppingg5]] = g5/2
### add tip sites and hoppings from them
tiphopping=0.001
tipleadhopping=1
sys[a(0, 0, -1)] = 0
sys[a(0,0,-1),a(0,0,0)] = tiphopping
sys[b(0, 0, -1)] = 0
sys[b(0, 0, -1), b(0, 0, 0)] = tiphopping
tipleada=kwant.Builder(kwant.TranslationalSymmetry([0,0,-2]))
tipleadb = kwant.Builder(kwant.TranslationalSymmetry([0, 0, -2]))
tipleada[a(0,0,-2)]=0
tipleada[a(0, 1, -2)] = 0
tipleada[a(0, 1, -2),a(0, 0, -2)] = 0
tipleada[a(0, 0, -1),a(0, 0, -2)] = tipleadhopping
tipleadb[b(0, 0, -2)] = 0
tipleadb[b(0, 0, -1), b(0, 0, -2)] = tipleadhopping
tipleadb[b(0, 1, -2)] = 0
tipleadb[b(0, 1, -2),b(0, 0, -2)] = 0
Wlead=size/2-1.5
symvecs=[[1, 0, 0], [sin_30,cos_30, 0], [1-sin_30,-cos_30, 0], [-1, 0, 0], [-sin_30,-cos_30, 0], [-1+sin_30,cos_30, 0]]
leadsymm = [kwant.TranslationalSymmetry(vec) for vec in symvecs]
leads = [kwant.Builder(sym) for sym in leadsymm]
leadregions=[lambda pos: ((-Wlead <= vec[0]*pos[1]-vec[1]*pos[0] <= Wlead) and (0 <= pos[2] <= Nl-1)) for vec in symvecs]
sys.attach_lead(tipleada)
sys.attach_lead(tipleadb)
for l in range(6):
leads[l][lat.shape(leadregions[l],(0,0,0))]=LeadPot
leads[l][[kwant.builder.HoppingKind(*hopping) for hopping in hopping0]] = g0hopping
leads[l][[kwant.builder.HoppingKind(*hopping) for hopping in hoppingg1]] = g1
leads[l][[kwant.builder.HoppingKind(*hopping) for hopping in hoppingg4]] = g4hopping
leads[l][[kwant.builder.HoppingKind(*hopping) for hopping in hoppingg3]] = g3hopping
leads[l][[kwant.builder.HoppingKind(*hopping) for hopping in hoppingg2]] = g2 / 2
leads[l][[kwant.builder.HoppingKind(*hopping) for hopping in hoppingg5]] = g5 / 2
sys.attach_lead(leads[l].substituted(peirels='peirels_lead'+str(l)))
# sys.attach_lead(leads[1])
print("hoppings ready")
for x in sys.sites():
x.family.norbs = 1
def family_color(site):
if site.family == a:
return 'black'
elif site.family == b:
return 'blue'
elif site.family==c:
return 'gray'
else:
return 'cyan'
def edgecolor(site):
if site.family == a:
return 'black'
elif site.family == b:
return 'blue'
elif site.family==c:
return 'gray'
else:
return 'cyan'
# axis=matplotlib.axes.Axes()
kwant.plot(sys, num_lead_cells=3, hop_lw=0.02, site_size=0.1, show=False, site_color=family_color, site_edgecolor=edgecolor,
hop_color='black') # , ax=axis)
#kwant.plot(leads[1], num_lead_cells=3, hop_lw=0.02, site_size=0.1, show=False, site_color=family_color,
# site_edgecolor=edgecolor, hop_color='black') # , ax=axis)
plt.show(block=False)
# print list(sys.site_value_pairs())
# print [sys[site] for site in sys.sites()]
return sys.finalized()
def gauss(x,broad):
if np.abs(x)>6*broad:
return 0
else:
return exp(-x*x/(2*broad*broad))/(broad*sqrt(2*pi))
def compute_ldos(sys,phi, depth, width,gate):
# Compute some eigenvalues of the closed system
Ham_mat = sys.hamiltonian_submatrix(sparse=True,params={'phi':phi,'depth':depth,'width':width,'gate':gate})
#sparse.csc_matrix(sys.hamiltonian_submatrix(sparse=True,params={'phi':phi,'depth':depth,'width':width,'gap':gap}))
#this gives the indices of A and B sites in the middle of the circular region
siteA= sys.id_by_site[a(0, 0, 0)]
siteB = sys.id_by_site[b(0, 0, 0)]
ev, es = sla.eigsh(Ham_mat,k=4000,sigma=0.001, which='LM')
weightA=pow(abs(es[siteA]),2)
weightB=pow(abs(es[siteB]),2)
epoints=np.linspace(-0.1,0.1,400)
DOSA= [sum([w*gauss(e-ev,0.0015) for (w,ev) in zip(weightA,ev)]) for e in epoints]
DOSB = [sum([w * gauss(e - ev, 0.0015) for (w, ev) in zip(weightB, ev)]) for e in epoints]
# print(ev)
# print(weightA)
# selection=weightA>0.005
# print(np.stack((ev,weightA)).transpose()[selection])
# histA,bin_edges = np.histogram(ev[selection],bins=50,range=(-0.5,0.5),weights=weightA[selection])
# histB,bin_edges = np.histogram(ev[selection], bins=50, range=(-0.5, 0.5), weights=weightB[selection])
#print(epoints,DOSA)
return [DOSA,DOSB]
def compute_ldos1(sys,phi, depth, width,gate):
# Compute some eigenvalues of the closed system
Ham_mat = sys.hamiltonian_submatrix(sparse=True,params={'phi':phi,'depth':depth,'width':width,'gate':gate})
#sparse.csc_matrix(sys.hamiltonian_submatrix(sparse=True,params={'phi':phi,'depth':depth,'width':width,'gap':gap}))
#this gives the indices of A and B sites in the middle of the circular region
siteA= sys.id_by_site[a(0, 0, 0)]
siteB = sys.id_by_site[b(0, 0, 0)]
def LDOS(e):
ev, es = sla.eigsh(Ham_mat,k=30,sigma=e, which='LM')
weightA=pow(abs(es[siteA]),2)
weightB=pow(abs(es[siteB]),2)
return [sum([w * gauss(e - ev, 0.0015) for (w, ev) in zip(weightA, ev)]),sum([w * gauss(e - ev, 0.0015) for (w, ev) in zip(weightB, ev)])]
epoints=np.linspace(-0.1,0.1,100)
DOS = [LDOS(e) for e in epoints]
return np.array(DOS).T
# print(ev)
# print(weightA)
# selection=weightA>0.005
# print(np.stack((ev,weightA)).transpose()[selection])
# histA,bin_edges = np.histogram(ev[selection],bins=50,range=(-0.5,0.5),weights=weightA[selection])
# histB,bin_edges = np.histogram(ev[selection], bins=50, range=(-0.5, 0.5), weights=weightB[selection])
#print(epoints,DOSA)
return [DOSA,DOSB]
def compute_ldos2(sys,phi, depth, width,gate):
# Compute some eigenvalues of the closed system
Ham_mat = sys.hamiltonian_submatrix(sparse=False,params={'phi':phi,'depth':depth,'width':width,'gate':gate})
#sparse.csc_matrix(sys.hamiltonian_submatrix(sparse=True,params={'phi':phi,'depth':depth,'width':width,'gap':gap}))
#this gives the indices of A and B sites in the middle of the circular region
siteA= sys.id_by_site[a(0, 0, 0)]
siteB = sys.id_by_site[b(0, 0, 0)]
ev, es = np.linalg.eigh(Ham_mat)
weightA=pow(abs(es[siteA]),2)
weightB=pow(abs(es[siteB]),2)
epoints=np.linspace(-0.1,0.1,400)
DOSA= [sum([w*gauss(e-ev,0.0015) for (w,ev) in zip(weightA,ev)]) for e in epoints]
DOSB = [sum([w * gauss(e - ev, 0.0015) for (w, ev) in zip(weightB, ev)]) for e in epoints]
def compute_ldos3(sys, phi, depth, width, gate,epoints:np.linspace(-0.1, 0.1, 400)):
# Compute some eigenvalues of the closed system
print("computing LDOS for fi="+str(phi))
#Ham_mat = sys.hamiltonian_submatrix(sparse=True, params={'phi': phi, 'depth': depth, 'width': width, 'gate': gate})
# sparse.csc_matrix(sys.hamiltonian_submatrix(sparse=True,params={'phi':phi,'depth':depth,'width':width,'gap':gap}))
# this gives the indices of A and B sites in the middle of the circular region
LeadsB=[[0,0,phi] for i in range(6)]
peirels_sysLeadList=list(gauge([0,0,phi],*LeadsB))
siteA = sys.id_by_site[a(0, 0, 0)]
siteB = sys.id_by_site[b(0, 0, 0)]
lead_params={'peirels_lead'+str(i):peirels_sysLeadList[i+1] for i in range(6)}
params = {'peirels':peirels_sysLeadList[0], 'depth': depth, 'width': width, 'gate': gate, **lead_params}
DOS = [kwant.ldos(sys,e,params=params)[[siteA,siteB]] for e in epoints]
return np.array(DOS).T
# print(ev)
# print(weightA)
# selection=weightA>0.005
# print(np.stack((ev,weightA)).transpose()[selection])
# histA,bin_edges = np.histogram(ev[selection],bins=50,range=(-0.5,0.5),weights=weightA[selection])
# histB,bin_edges = np.histogram(ev[selection], bins=50, range=(-0.5, 0.5), weights=weightB[selection])
#print(epoints,DOSA)
return [DOSA,DOSB]
def compute_conductance(sys, phi, depth, width, gate,epoints:np.linspace(-0.1, 0.1, 400)):
# Compute some eigenvalues of the closed system
print("computing LDOS for fi="+str(phi))
#Ham_mat = sys.hamiltonian_submatrix(sparse=True, params={'phi': phi, 'depth': depth, 'width': width, 'gate': gate})
# sparse.csc_matrix(sys.hamiltonian_submatrix(sparse=True,params={'phi':phi,'depth':depth,'width':width,'gap':gap}))
# this gives the indices of A and B sites in the middle of the circular region
LeadsB=[[0,0,0],[0,0,0]]+[[0,0,phi] for i in range(6)]
peirels_sysLeadList=list(gauge([0,0,phi],*LeadsB)) ### gauges for system and leads
siteA = sys.id_by_site[a(0, 0, 0)]
siteB = sys.id_by_site[b(0, 0, 0)]
lead_params={'peirels_lead'+str(i):peirels_sysLeadList[i+3] for i in range(6)}
params = {'peirels':peirels_sysLeadList[0], 'depth': depth, 'width': width, 'gate': gate, **lead_params}
dat=[]
for en in epoints:
smatrix = kwant.smatrix(sys, energy=en, params=params, in_leads=[0,1],out_leads=[3])
dat.append([smatrix.transmission(lead_out=3, lead_in=0), smatrix.transmission(lead_out=3, lead_in=1)])
return np.array(dat)
# print(ev)
# print(weightA)
# selection=weightA>0.005
# print(np.stack((ev,weightA)).transpose()[selection])
# histA,bin_edges = np.histogram(ev[selection],bins=50,range=(-0.5,0.5),weights=weightA[selection])
# histB,bin_edges = np.histogram(ev[selection], bins=50, range=(-0.5, 0.5), weights=weightB[selection])
#print(epoints,DOSA)
return [DOSA,DOSB]
path = os.getcwd()
scaling=30
Btophi=0.0000919035*pow(scaling,2)
g0=3.16/scaling
g1=0.39
g4=0.14/scaling
g3=0.315/scaling
g2=-0.020
g5=0.044
DeltaAB=0.02# 0.02
Ef=-0.0213
Nl=3
sys=make_system(size=5)
print("system is ready")
gauge = kwant.physics.magnetic_gauge(sys)
print("gauge is ready")