Dear community,
as I have seen that the creation of a (zero-bias) transmission spectrum, e.g. for a nanotube, takes much longer than the calculation of the bandstructure, I have written a (simple) function that generates a transmission spectrum out of a given bandstructure. The calculation time of the transmission is in the range of seconds and almost not independent on the resolution given.
@ATK-developers / experienced users: What does the implemented ATK-feature do else to generate a transmission spectrum? May this approach used here generate errors for special systems?
Best regards!
from NanoLanguange
from numpy import * # sorry for this dirty import of numpy
from NanoLanguage import *
def create_transmission_atk(band, emin = -4, emax = 4, npoints = 1000):
# create transmission function, band is an ATK-bandstructure object
# [emin, emax] define the energy interval
# npoints gives the resolution of the interval (+1 is added to this value, later on)
energies = array(band.evaluate()) # all the energy points of the bandstructure in an array
return create_transmission(energies, emin = emin, emax = emax, npoints = npoints)
# the next function may be used also with other programs than ATK, no nano languange is needed
def create_transmission(energies, emin = -4, emax = 4, npoints = 1000):
# create transmission function
# energies = the energy points of the bandstructure in an array, each band separated
epoints = linspace(emin, emax, npoints+1)
transmission = zeros(npoints+1)
nbands = size(energies[0,:])
for i in range(nbands): # loop over bands
tmp = energies[:,i] # band number i
# print tmp
l = size(tmp)
nextreme = [0] # minima and maxima of the band
de2 = 0; de = 0;
for j in range(1,l-1):
de2 = de
de = tmp[j]-tmp[j-1]
if (de2*de < 0):
# does the sign of the energy difference change? (local extremum)
nextreme.append(j-1)
nextreme.append(l-1)
for k in range(size(nextreme)-1):
# all the minima and maxima
istart = int((tmp[nextreme[k]]-emin) / (emax - emin) * npoints)
iend = int((tmp[nextreme[k+1]]-emin) / (emax - emin) * npoints)
if (istart < 0):
istart = 0
if (iend < 0):
iend = 0
if (istart > npoints ):
istart = npoints
if (iend > npoints ):
iend = npoints
if istart > iend:
istart, iend = iend, istart
transmission[istart:iend] = transmission[istart:iend] + ones(iend - istart)
return array([epoints, transmission])