Further analysis of two-probe systems

Table of Contents

Introduction

This tutorial analyzes the Li-H2-Li two-probe system introduced in tutorial Li-H2-Li two-probe system using additional analysis functions implemented in NanoLanguage. By doing this we will be able to explain some of the intricate features of our two-probe system. We will discuss calculating:

  • A voltage drop and perform a potential analysis.

  • Projected eigenstates.

  • Local density of states.

Prerequisites

To perform the steps in this tutorial, you must have completed the previous tutorial Li-H2-Li two-probe system, as we will use the converged self-consistent calculations for both zero and finite bias produced there, as well as the VNLFile containing the atomic configuration of the Li-H2-Li two-probe system. We will also use Virtual NanoLab (VNL) to visualize our results, but all calculation are performed solely using ATK.

Projected eigenstates

Calculating the projected energy spectrum

The function calculateProjectedHamiltonianEnergySpectrum() calculates the energy spectrum of the molecular projected self-consistent Hamiltonian (MPSH). By this, we mean that the self-consistent Hamiltonian is projected onto specified atoms in the central region, and then diagonalized to produce an energy spectrum. This can be used to show how the molecular levels for a molecule (e.g. hydrogen) are affected when placed between between the two electrodes.

The code sample below shows how the energy spectrum, projected onto the hydrogen atoms, is calculated. We export the calculated spectrum to a VNLFile, which can be imported and visualized in VNL.

from ATK.TwoProbe import *

# Restore calculation
scf = restoreSelfConsistentCalculation('lih2li-scf.nc')

# Calculate energy spectrum for the two H atoms
mpsh_spectrum = calculateProjectedHamiltonianEnergySpectrum(
    scf, projection_atoms = [3,4]
    )

# Store energy spectrum in a VNL file
vnl_file = VNLFile("lih2li-mpsh.vnl")
vnl_file.addToSample(mpsh_spectrum,'lih2li-mpsh')

lih2li-mpsh-spectrum.py

The projection_atoms specify which atoms we want to calculate the eigenstates for. The numbers refer to the order of the elements in the central region, as they were specified in the TwoProbeConfiguration used in the self-consistent field calculation. In the above script, we have specified atom 3 and 4 corresponding to the two hydrogen atoms.

If you cannot remember or do not know which atoms that are in the central region, the following script will display all elements in the central region along with their Cartesian coordinates.

def displayCentralRegionAtoms(atomic_configuration):
    '''
    This function will print information about the atoms located
    in the central region of a two-probe system. This information
    involves:
    * Internal order (number)
    * Element type
    * Cartesian coordinates of the atom
    '''
    print 'Central region atomic configuration:'
    print '='*50
    print 'Number\tElement\tCartesian coordinates (Ang)'
    for i in  range(len(atomic_configuration.elements())):
        print i,'\t',atomic_configuration.elements()[i].symbol(),'\t',
        for x in atomic_configuration.cartesianCoordinates()[i]:
            print x.inUnitsOf(Angstrom),'\t',
        print
    print '='*50

displayCentralRegion.py

You can use this function in the following way:

from ATK.TwoProbe import *
from displayCentralRegion import displayCentralRegionAtoms

vnl_file=VNLFile("lih2li.vnl")
atomic_configuration_dict = vnl_file.readAtomicConfigurations()
atomic_configuration = atomic_configuration_dict["lih2li"]
displayCentralRegionAtoms(atomic_configuration)
      

which should print the following to your screen provided you have been using the file lih2li.vnl for storing the atomic configuration used throughout these examples.

Atoms located in the scattering region:
==================================================
Number  Element Cartesian coordinates
0       Li      [0.0 Ang 0.0 Ang -8.568 Ang]
1       Li      [0.0 Ang 0.0 Ang -5.668 Ang]
2       Li      [0.0 Ang 0.0 Ang -2.768 Ang]
3       H       [0.0 Ang 0.0 Ang -0.402 Ang]
4       H       [0.0 Ang 0.0 Ang 0.402 Ang]
5       Li      [0.0 Ang 0.0 Ang 2.768 Ang]
6       Li      [0.0 Ang 0.0 Ang 5.668 Ang]
7       Li      [0.0 Ang 0.0 Ang 8.568 Ang]
==================================================

This confirms that the atoms chosen as projection_atoms indeed were our hydrogen atoms.

Energy spectrum for hydrogen atoms in a hydrogen molecule and for the hydrogen atoms in the two-probe system. The HOMO/LUMO gap is smaller for the hydrogen atoms in the two-probe system.

Figure 40: Energy spectrum for hydrogen atoms in a hydrogen molecule and for the hydrogen atoms in the two-probe system. The HOMO/LUMO gap is smaller for the hydrogen atoms in the two-probe system.


By comparing the molecular projected energy spectrum for the hydrogen atoms in the two-probe system with that of molecular hydrogen, we can see that the energy gap between the HOMO and the LUMO is smaller for the hydrogen atoms in the two-probe system. This reduction of the HOMO–LUMO gap is directly responsible for the large value of the transmission coefficient of the hydrogen molecule observed experimentally.

Transmission spectrum for the Li-H2-Li system along with the molecular projected energy spectrum for the hydrogen atoms. Actually, this figure was produced using a DoubleZetaPolarized basis set also for the lithium atoms for a more accurate description.

Figure 41: Transmission spectrum for the Li-H2-Li system along with the molecular projected energy spectrum for the hydrogen atoms. Actually, this figure was produced using a DoubleZetaPolarized basis set also for the lithium atoms for a more accurate description.


Figure 41 shows the energy spectrum of the hydrogen atoms in the two-probe system along with the transmission spectrum for the entire Li-H2-Li two-probe system. Here, we see that only the LUMO of the hydrogen atoms take part in conducting electrons from one electrode to the other, as that is the only orbital which is located at energies where transmission is noticeable.

Visualizing the eigenstates of the projected spectrum

The calculateProjectedHamiltonianEigenstates() function calculates wave-functions (i.e. eigenstates) of the projected molecular Hamiltonian discussed just above. This way, one can study how the molecular orbitals for a molecule are changed when the molecule is placed between between the two electrodes.

The script below shows how to calculate the eigenstates of a molecule in a two-probe scattering region using the calculateProjectedHamiltonianEigenstates() method. We want to analyze the HOMO and LUMO eigenstates, corresponding to the first and second eigenstate for a hydrogen molecule. The complete script for doing this is shown below.

from ATK.TwoProbe import *

# Restore calculation
scf = restoreSelfConsistentCalculation('lih2li-scf.nc')

# Reopen old two-probe configuration
vnl_file=VNLFile("lih2li.vnl")
atomic_configuration = vnl_file.readAtomicConfigurations()["lih2li"]

# Calculate HOMO and LUMO eigenstates for the H atoms in the two-probe system
eigenstates = calculateProjectedHamiltonianEigenstates(
    scf, projection_atoms = [3,4],
    quantum_numbers = [0,1]
    )

# Store results in VNL files
vnl_file = VNLFile("lih2li-mpsh.vnl")
vnl_file.addToSample(atomic_configuration,'lih2li_mpsh')
for eigenstate in eigenstates:
    vnl_file.addToSample(eigenstate, 'lih2li_mpsh')

lih2li-mpsh.py

Remember, that in Python the first element in a list has the index zero. So when we specify the quantum states as

quantum_numbers = [0,1]

we mean the first and the second eigenstate, which in a hydrogen molecule correspond to the HOMO and LUMO states.

The produced file can now be loaded into VNL where the orbitals can be visualized.

Voltage drop

In this section we will analyze how the effective potential of the two-probe system changes when we apply a bias between the lithium electrodes.

First, we import the necessary modules, restore the TwoProbeConfiguration and the previously performed calculations, for zero and finite bias (1 Volt).

from ATK.TwoProbe import *

# Reopen old two-probe configuration
vnl_file = VNLFile("lih2li.vnl")
atomic_configuration = vnl_file.readAtomicConfigurations()["lih2li"]

# Restore results from previous calculations
bias0V = restoreSelfConsistentCalculation('lih2li-bias-0.0.nc')
bias1V = restoreSelfConsistentCalculation('lih2li-bias-1.0.nc')

The effective potential of the two-probe system is calculated using the calculateEffectivePotential() method in NanoLanguage. To visualize the voltage drop over the two-probe system we need to calculate the effective potential with zero bias and the desired finite bias (1 Volt) across the electrodes. Using the executeSelfConsistentCalculation() we can start from the previously performed SCF-calculation which will save us some time. The difference between the two potentials (i.e. the voltage drop) is then calculated by subtracting the calculated effective potentials from each other. These steps are shown in the script below.

# Calculate effective potentials ...
pot_0V = calculateEffectivePotential(bias0V)
pot_1V = calculateEffectivePotential(bias1V)

# ... and find the difference = the voltage drop
potential_drop = pot_1V - pot_0V

Finally, we store our results in a VNLFile in order to visualize them using VNL. This involves storing the atomic configuration along with the effective potentials in order to visualize the position of the atoms in the two-probe systems; an examples is shown in Figure 42.

# Store result in a new VNL file
vnl_file = VNLFile("lih2li-voltdrop.vnl")
vnl_file.addToSample(atomic_configuration,'lih2li-voltdrop')
vnl_file.addToSample(potential_drop,'lih2li-voltdrop')
Contour plot of the effective potential with an applied bias of 1 Volt over the two-probe system. The abrupt change in the potential at the right electrode shows that our calculation should include additional surface atoms in order to properly screen the induced electric field.

Figure 42: Contour plot of the effective potential with an applied bias of 1 Volt over the two-probe system. The abrupt change in the potential at the right electrode shows that our calculation should include additional surface atoms in order to properly screen the induced electric field.


The complete script which accomplishes all of the above steps is provided below for easy reference.

from ATK.TwoProbe import *

# Reopen old two-probe configuration
vnl_file = VNLFile("lih2li.vnl")
atomic_configuration = vnl_file.readAtomicConfigurations()["lih2li"]

# Restore results from previous calculations
bias0V = restoreSelfConsistentCalculation('lih2li-bias-0.0.nc')
bias1V = restoreSelfConsistentCalculation('lih2li-bias-1.0.nc')

# Calculate effective potentials ...
pot_0V = calculateEffectivePotential(bias0V)
pot_1V = calculateEffectivePotential(bias1V)

# ... and find the difference = the voltage drop
potential_drop = pot_1V - pot_0V

# Store result in a new VNL file
vnl_file = VNLFile("lih2li-voltdrop.vnl")
vnl_file.addToSample(atomic_configuration,'lih2li-voltdrop')
vnl_file.addToSample(potential_drop,'lih2li-voltdrop')

lih2li-voltdrop.py

Local density of states

The local, or spatially resolved, density of states (DOS) are calculated using the calculateLocalDensityOfStates() function available in the ATK.TwoProbe module. An example script calculating the LDOS for our two-probe system is shown below.

from ATK.TwoProbe import *

# Restore calculation
lih2li_scf = restoreSelfConsistentCalculation('lih2li-scf.nc')

# Read old atomic configuration 
vnl_file = VNLFile("lih2li.vnl")
atomic_configuration = vnl_file.readAtomicConfigurations()["lih2li"]

# Calculate electron density from old NetCDF data
electron_density = calculateElectronDensity(lih2li_scf)

# Calculate local DOS for non-electrode atoms
ldos = calculateLocalDensityOfStates(
    lih2li_scf,
    energy = 0.0*eV,
    quantum_number = (0.0,0.0)
    )

# Store obtained results in vnl file using
# different IDs
vnl_file = VNLFile("lih2li-ldos.vnl")
vnl_file.addToSample(atomic_configuration,'lih2li-ldos')
vnl_file.addToSample(electron_density, 'lih2li-ldos')
vnl_file.addToSample(ldos, 'lih2li-ldos')

lih2li-ldos.py

We calculate the LDOS at the Fermi level. The variable quantum_numbers corresponds to the k-point; for our one-dimensional system we naturally use the two-dimensional Γ point, i.e. k=(0.0,0.0).

We see a substantial density of states located at the hydrogen atoms (and little or none elsewhere) which shows that for a moderate bias, the LUMO of the hydrogen molecule is the origin of the eigenchannel that carries most of the current.

Isosurface showing the local DOS of the two-probe system. The isosurface shown corresponds to 0.01216 states/(Å3 eV). A considerable density of states is located at the hydrogen atoms.

Figure 43: Isosurface showing the local DOS of the two-probe system. The isosurface shown corresponds to 0.01216 states/(Å3 eV). A considerable density of states is located at the hydrogen atoms.