Transmission tutorial

Requirements

Software components

  • nanotools

  • NanoDCAL+

Pseudopotentials

  • C_AtomicData.mat

Copy the mat file from the pseudo database to the current working directory and export NANODCALPLUS_PSEUDO=$PWD.

Briefing

This tutorial presents a minimal example of transmission calculation for a two-probe transport system. The system to be addressed is a crystalline carbon nano-tube (CNT).

Setup

python script

from nanotools import Atoms, Cell, Species, System, TotalEnergy, Transmission, TwoProbe
import numpy as np

cell = Cell(avec=[[20.0, 0.0, 0.0], [0.0, 20.0, 0.0], [0.0 , 0.0 , 2.4595]], resolution=0.2)
atoms= Atoms(positions="cnt.xyz")
sys = System(cell=cell, atoms=atoms)
sys.kpoint.set_grid([1,1,50])
center = TotalEnergy(sys)
left = center
right= center

dev = TwoProbe(left=left, center=center, right=right, transport_axis=2)
dev.center.solver.set_mpi_command("mpiexec -n 4")
# dev.center.solver.mpidist.zptprc=4
dev.solve()

cal = Transmission.from_twoprobe(twoprb=dev)
cal.solve(energies = np.linspace(-5, 5, num=101))
cal.plot(filename="cnt_transm.png", show=True)

structure file cnt.xyz, in Cartesian coordinates

12
CNT
C 8.08866505    10.69566903     0.61487804
C 8.44186547    11.30743011     1.84462196
C 9.64679958    12.00309914     1.84462196
C 10.35320042   12.00309914     0.61487804
C 11.55813453   11.30743011     0.61487804
C 11.91133495   10.69566903     1.84462196
C 11.91133495   9.30433097      1.84462196
C 11.55813453   8.69256989      0.61487804
C 10.35320042   7.99690086      0.61487804
C 9.64679958    7.99690086      1.84462196
C 8.44186547    8.69256989      1.84462196
C 8.08866505    9.30433097      0.61487804

A two-probe transport system

Explanations

As sketched in the above diagram, a two-probe transport system consists of three sub-systems, corresponding to the two electrical leads and a quantum scattering structure in between. The leads are regarded as in thermal equilibrium and therefore can be resolved with the basic DFT calculator under periodic boundary conditions. The remaining task is solving the quantum scattering problem with lead electronic structures taken as boundary conditions. We shall first perform a self-consistent calculation for our CNT structure, and then compute the very important quantity, transmission, which indicates the maximum possible electric current at a given energy level.

unit cell of carbon nano-tube

System definition

The following code section describes a unit cell of an armchair carbon nano-tube (see figure above)

cell = Cell(avec=[[20.0, 0.0, 0.0], [0.0, 20.0, 0.0], [0.0 , 0.0 , 2.4595]], resolution=0.2)
atoms= Atoms(positions="cnt.xyz")
sys = System(cell=cell, atoms=atoms)

A grid of reciprocal (k) points is also needed for the periodic calculation of lead structures. This is specified by

sys.kpoint.set_grid([1,1,50])

We set only one k-point in the transversal plane since there is vacuum buffer all around the nanotube. Along the transport direction, on the other hand, a sufficient number of k-points should be used since lead structures are periodic. In general, only one k-grid needs be specified for the whole two-probe calculation: k-points along the transport dimension are automatically removed when it comes to the NEGF calculation for the central region.

The sys object is then used to initialize a TotalEnergy calculator (see tutorial_etot.md)

center = TotalEnergy(sys)

The TwoProbe calculator, which manages the work-flow of self-consistent calculations, can be initialized as

left = center
right= center
dev = TwoProbe(left=left, center=center, right=right, transport_axis=2)

where left, center, and right are TotalEnergy calculators for the respective sub-systems. In this tutorial, the three sub-systems are structually identical. Therefore, we simply assign the same calculator twice

Since it happens quite often that a few or all of the sub-systems in a two-probe system share the same structure, nanotools provides a simplified interface for this case

dev = TwoProbe(center=center, transport_axis=2)

Now left and right are assumed identical to center. When only right is omitted, eg.

dev = TwoProbe(left=left, center=center, transport_axis=2)

right is assumed identical to left.

Nevertheless, note that one must explicitly specify the transport_axis parameter (along which dimension transport occurs) in defining a TwoProbe calculator. In the current example, transport_axis=2 corresponds to the z-dimension (remember that python uses 0-based indexing).

Self-consistent calculation

We then launch the self-consistent calculation by typing in

dev.center.solver.set_mpi_command("mpiexec -n 4")
dev.center.solver.mpidist.zptprc=4
dev.solve()

The first two lines set mpi-related parameters to accelerate the calculation. Here we assign 4 processors. The zptprc parameter indicates the number of energy points at which Green functions are computed in parallel. This parameter is better to be maximized for small simulation tasks.

Upon executing dev.solve(), a few json files will appear in the directory; they are left.json, right.json, and nano_2prb_in.json. In many cases the leads may be structurally identical; if so, right.json will be omitted. Self-consistent calculations are first carried out for leads, using the rescuplus executable, with left.json or right.json as its input files. The outputs are written in left_out.json, left_out.h5, right_out.json and right_out.h5. After the lead calculations are finished, nanodcalplus will be executed with nano_2prb_in.json as its input file. nanodcalplus performs the self-consistent calculation for the quantum scattering problem, and the results will be saved in nano_2prb_out.json and center_out.h5. Note that center_out.h5 contains charge densities and potentials only of the central scattering region. All the workflow described here is managed by dev.solve().

One may restart a two-probe calculation based on an existing charge-density file, e.g.

...
dev.center.solver.restart.densityPath = "center_out.h5"
dev.solve()

Transmission

The self-consistent calculation must precedes the transmission calculation, since the latter requires existing ground-state density data, i.e. _out.h5 files.

The Transmission calculator is dedicated to the transmission computation. In our case, we can simply create such a calculator from the existing TwoProbe object and use its solve method to launch the calculation.

cal = Transmission.from_twoprobe(twoprb=dev)
cal.solve(energies = np.linspace(-5, 5, num=101))

Finally, we visualize the transmission profile by typing in

cal.plot(filename="cnt_transm.png", show=True)

You should see something similar to

transmission profile of carbon nano-tube

Since we are simulating a perfectly intrinsic carbon nano-tube, its transmission profile shows a step-wise shape. The integer transmission value at each step simply equals the band degeneracy.