Transport through a p-n Junction in Graphene


The subsequent program shows how simple the calculation of the transport properties through a graphene p-n junction can be done with the TQT library.

The electronic structure of the graphene ribbon is modeled by the atomistic tight-binding Hamiltonian GrapheneZZ2.
The lead modes of the zig-zag ribbon are calculated by means of the LeadWavePacket class and the time evolution is computed by the FaberPropagator.
The observable Transmission stores correlation functions between different wave packets during the propagation and returns transmission amplitudes at the end of the program.

Interplay of the TQT classes in the subsequent example.


#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;
}