Bulk materials

Table of Contents

When you take the leap from the investigation of basic molecular system to infinite bulk and crystals systems, ATK offers you a broad selection of additional tools tailored for handling the additional challenges put forward by such systems. In particular, you will have access to

Defining a bulk system

Little effort is required to set up crystals or bulk systems using NanoLanguage. Two basic steps are required, namely

  • choosing the Bravais lattice and the specific lattice constants that describe the crystal

  • specifying the atomic constituents of the bulk crystal

A simple script for defining a silicon crystal is shown below

from ATK.KohnSham import *

# Create Bravais lattice 
lattice_constant = 5.43*Angstrom
fcc_lattice = FaceCenteredCubic(lattice_constant)

# Specify bulk configuration with 2 silicon atoms
# as basis in a FCC Bravais lattice
si_fcc = BulkConfiguration(
    bravais_lattice = fcc_lattice,
    elements = 2*[Silicon],
    fractional_coordinates = [
        [0.00, 0.00, 0.00], 
        [0.25, 0.25, 0.25]
        ]
    )

# Display Cartesian coordinates for silicon crystal
from printBulkConfig import printBulkConfig
printBulkConfig(si_fcc)

# Store crystal structure in a VNL file for later use
vnl_file=VNLFile("si.vnl")
vnl_file.addToSample(si_fcc,"si_fcc")

bulk-setup.py

  1. Specify the Bravais lattice and the lattice constant of the silicon crystal using the FaceCenteredCubic class. NanoLanguage gives you quick and easy access to all 14 Bravais lattices enabling you to build and study any crystal you desire,

  2. Add the specified crystal to a FaceCenteredCubic object. Use this object for performing DFT calculations and further analysis.

  3. Print the silicon bulk configuration to the screen using the function printBulkConfig().

  4. Store the silicon crystal structure in a VNLFile making it ready to be loaded by other NanoLanguage scripts.

Download the file printBulkConfig.py to the same folder as bulk-setup.py and issue the following command

atk bulk-setup.py

The structure of the silicon crystal is shown below in Figure 5.

The structure of the silicon fcc crystal, plotted using VNL. The unit cell of the crystal is indicated by a wire box.

Figure 5: The structure of the silicon fcc crystal, plotted using VNL. The unit cell of the crystal is indicated by a wire box.


A self-consistent bulk calculation

Once the crystal geometry and its atomic constituents are defined, the physical properties of the crystal can determined using the relevant NanoLanguage functions and classes. To do this, the following basic steps are required

  • choose the method that should be used for running the DFT calculation

  • run the DFT calculation

  • use the large variety of NanoLanguage functions for extracting the desired physical properties and values from the DFT calculation

Here is a NanoLanguage script that defines and runs a DFT calculation for the bulk silicon system

from ATK.KohnSham import *
import ATK

# Restore previously defined Silicon structure
si_fcc = VNLFile("si.vnl").readAtomicConfigurations()["si_fcc"]

#Specify NetCDF file for storing results
ATK.setCheckpointFilename('si_gga_dzp.nc')

# Define new KohnShamMethod using a non-default
# exchange-correlation potential (GGA)
method = KohnShamMethod(
    exchange_correlation_type = GGA.PBE,
    basis_set_parameters = basisSetParameters(type=AtomicOrbitals.DZP),
    brillouin_zone_integration_parameters = \
        brillouinZoneIntegrationParameters(monkhorst_pack_parameters = [4,4,4])
    )

# Perform the actual calculation
gga_calculation = method.apply(atomic_configuration = si_fcc)

bulk-gga_calculation.py

  1. Load the definition of the system from a previously stored VNLFile.

  2. Call the NanoLanguage function VNLFile and instruct ATK to store the result of the DFT calculation to a checkpoint file. In this way, you can load the result of the calculation from a different script and extract other relevant physical quantities.

  3. Specify that a KohnShamMethod should be used for solving the DFT problem. In this case, we overwrite several of the default parameters of the method by requesting:

    • A different exchange-correlation functional.

    • A specific basis set.

    • The number of k-points that should be used in the calculation.

  4. Perform the DFT calculation.

Run the script by issuing the following command from the command line

atk bulk-gga_calculation.py

Once this script has been processed, the checkpoint file si_gga_dzp.nc will be stored on disk ready to be loaded and analyzed by other NanoLanguage scripts.

Calculating the Bloch function

Having finished the DFT calculation of your system, a variety of information can be extracted. Specifically for bulk systems, NanoLanguage gives you access to

  • Fermi energies

  • Energy and band structure calculations

  • Bloch functions

For the above silicon system, here is is how to extract the Bloch function for a particular set of quantum numbers

from ATK.KohnSham import *

# Restore old NetCDF results
gga_calculation = restoreSelfConsistentCalculation('si_gga_dzp.nc')

# Calculate eigenstates
eigenstates = calculateEigenstates(
    self_consistent_calculation = gga_calculation,
    quantum_numbers = ( (0,1), (0.375,0.375,0.75) )
)

# Store eigenstates in a VNL file
vnl_file=VNLFile("si.vnl")
for eigenstate in eigenstates:
    vnl_file.addToSample(eigenstate, "si_fcc")

bulk-eigenstates.py

  1. Use restoreSelfConsistentCalculation() to load the DFT result from a previous calculation.

  2. Use calculateEigenstates() to calculate the Bloch state for a specific set of quantum numbers.

  3. Save the eigenstates to a VNLFile. You may then import this file into VNL for further examination of the Bloch function properties.

Run the script by issuing the following command from the command line

atk bulk-eigenstates.py

A plot of the Bloch function for the silicon crystal is shown in Figure 6.

Bloch function representing an eigenstate for a silicon crystal.

Figure 6: Bloch function representing an eigenstate for a silicon crystal.


Determining the band structure

Both the calculation and the subsequent analysis of a band structure calculation can be a very demanding task. ATK makes this challenge simple, supplementing you with a range of NanoLanguage functions for easy inspection and analysis of band structures.

For the silicon crystal, here are the required lines of code for setting up the Brillouin zone path and extracting the band structures data

from ATK.KohnSham import *

def lineOfVectorPoints(start_point,end_point,N=20):
    '''
    @return: A list containing (default: 20) k-points between two
    specified points in the Brillouin zone.
    '''
    from numpy import array
    points = []
    for i in range(N):
        new_point = (float(i)/(N-1),)*3*(array(end_point) - array(start_point))+start_point
        points.append(new_point)
    return points

# Define common symmetry points in the Brillouin zone of silicon
fcc_symmetry_points = {
    'G' : (0.000, 0.000, 0.000),
    'X' : (0.500, 0.000, 0.500), 
    'W' : (0.500, 0.250, 0.750), 
    'L' : (0.500, 0.500, 0.500), 
    'K' : (0.375, 0.375, 0.750), 
    'U' : (0.625, 0.250, 0.625) 
}

#Create line in Brillouin zone along which the
#band structure is calculated
start_point = fcc_symmetry_points['G']
end_point = fcc_symmetry_points['X']
band_k_points = lineOfVectorPoints(start_point,end_point,25)

#Restore old SCF calculation
calculation = restoreSelfConsistentCalculation('si_gga_dzp.nc')
band_structure = calculateEnergyBands(
    self_consistent_calculation = calculation,
    k_point_list = band_k_points)

#Extract calculated bands into a list
energy_bands = []
for band_index in range(band_structure.numberOfBands()):
    energy_bands.append(band_structure.band(band_index))

#print band energies in units of eV
for i in range(len(band_k_points)):
    print band_k_points[i][0],
    for band in range(band_structure.numberOfBands()):
        print energy_bands[band][i].inUnitsOf(eV),
    print

bulk-calculateBands.py

  1. A user-defined Python function for easing the task of generating points through the Brillouin zone.

  2. A list of standard symmetry points through the fcc Brillouin zone.

  3. Generate a line of points through the Brillouin zone.

  4. Load the DFT results from a previous DFT calculation of the silicon crystal.

  5. Calculate the band structure.

  6. Append each energy band to a Python list, so we can print it out.

  7. Print the respective energy bands defining the silicon band structure. In this way, the band structure can easily be plotted using standard 2D plotting software.

Run the script by issuing the following command from the command line

atk bulk-calculateBands.py > si_fcc_gga.dat

A plot illustrating the silicon band structure, using the output data from the above script, is shown in Figure 7

The GGA band structure of silicon between the Γ and X point, generated from the data produced by the presented NanoLanguage script.

Figure 7: The GGA band structure of silicon between the Γ and X point, generated from the data produced by the presented NanoLanguage script.