Transport durch einen p-n Übergang in Graphene
Das folgende Programmbeispiel zeigt wie einfach es ist mit Hilfe der TQT Biblothek den Transport durch einen Graphene p-n Übergang zu berechnen.
Die elektronische Struktur des Graphene Streifens wird mit dem atomistischen
tight-binding Hamiltonian GrapheneZZ2 modelliert.
Für den zig-zag Streifen werden die Lead Wellepakete mit der Klasse LeadWavePacket
berechnet und der Propagator FaberPropagator ist für die anschließende Zeitentwicklung
zuständig.
Die Observable Transmission speichert während der Propagation Korrelationsfunktionen
zwischen unterschiedlichen Wellenpaketen und berechnet zu Ende des Programms die
Transmissionsamplituden.
#include "tqt.h"
using namespace TQT;
//Define a Fermi function used for potential steps
REAL pot(REAL x, REAL x0, REAL a0)
{
return 1. / (1. + exp((x - x0) / a0));
}
int main()
{
//Run through all different bands
for (INDEX wp_id = 0; wp_id < 20; wp_id++)
{
//Define a graphene nanoribbon (length=500 unit cells, with=6*2 unit cells)
Grid grid(500, 6, 2.46 * SI_ANGS, 2.46 * SI_ANGS);
//Define atomistic graphene Hamiltonian and corresponding state to propagate
GrapheneZZ2 hamiltonian(grid);
Timestate state(hamiltonian);
//Define a time discretization and split it every 50 time steps
Timeline timeline(500.0e-15, .1e-15);
timeline.add_equalsplit(50);
//Define global parameters (split multiple valleys, energy bounds) of the leads
LeadParam leadparam(timeline, hamiltonian);
leadparam.set(LeadParam::SPLIT);
leadparam.set_Emin(-7.*SI_CHARGE_ELECTRON);
leadparam.set_Emax(5*SI_CHARGE_ELECTRON);
leadparam.info();
//Initialize two leads at -9nm and +9nm of the p-n junction and write bands
LeadWavePacket lead1(leadparam, -9. * SI_NM, grid.get_y0(), -9. * SI_NM,
grid.get_y1(), "lead1");
LeadWavePacket lead2(leadparam, 9. * SI_NM, grid.get_y1() - 1.e-10, 9. * SI_NM,
grid.get_y0(), "lead2");
lead1.write_band("band_lead1.plt");
lead2.write_band("band_lead2.plt");
//Add potential and left/right absorber to the Hamiltonian
{
REAL border = 40 * SI_NM;
REAL border_width = grid.get_x1()-border;
REAL x;
for (INDEX ix = 0; ix < grid.get_NX(); ix++)
for (INDEX iy = 0; iy < grid.get_NY(); iy++)
{
x = grid.get_x0() + ix * grid.get_dx();
hamiltonian.V(ix, iy) = .6 * pot(-x, 0., 1.492 * SI_NM) *
SI_CHARGE_ELECTRON;
hamiltonian.M(ix, iy) += .000001 * SI_CHARGE_ELECTRON;
hamiltonian.Vat(ix, iy) -= 0.15 * pot(x, -border-0.5*border_width,
border_width*0.3) * SI_CHARGE_ELECTRON;
hamiltonian.Vat(ix, iy) -= 0.15 * pot(-x, -border-0.5*border_width,
border_width*0.3) * SI_CHARGE_ELECTRON;
}
}
//Initialize a propagator using Faber polynomials with DeltaE=20, E0=0, d=0.4
FaberPropagator prop(timeline, state, 20. * SI_CHARGE_ELECTRON, 0., 0.4);
prop.set_Hamiltonian(hamiltonian);
//Define the norm observable and add it to the propagator
Norm norm(timeline, state);
prop.add(norm);
//Define the transmission observable for the band wp_id and analyze all
//amplitudes through lead1 and lead2 between -2.5eV and 1.8eV
Transmission transmission(timeline, state, lead1, wp_id, -2.5 *
SI_CHARGE_ELECTRON, 1.8* SI_CHARGE_ELECTRON);
transmission.add(lead2);
//Add the transmission to the propagator
prop.add(transmission);
//Calculate the time evolution
prop.runall();
//Write the time evolution of the norm
std::stringstream filename;
filename << "norm" << wp_id << ".nc";
norm.write_t(filename.str().c_str());
//Write the energy dependent transmission into all modes
filename.str("");
filename << "all_transmissions" << wp_id << ".dat";
transmission.write_E(filename.str().c_str());
//Write the energy dependent transmission into different leads
filename.str("");
filename << "sum_transmissions" << wp_id << ".dat";
transmission.write_E_sum(filename.str().c_str());
}//End loop through all different bands
return 0;
}