Adding disorder

Adding disorder

The purpose of this section is to provide a simple overview of the different types of disorder that can be added to KITE tight-binding calculations. The general character of our disorder implementation is one of the main features of KITE. To achieve this generality, the implementation follows a basic structure: the user specifies the disorder pattern to be included (that can be constricted to one unit cell or can connect neighboring unit cells) and the disorder pattern is reproduced randomly inside the sample, according to a defined concentration and statistical distribution..

After defining a lattice with the procedure explained in Getting Started), we can add disorder to our system. Usually, disorder can be modeled either as a modification of onsite potentials appearing on the lattice sites or as a combination of onsite potential and bond disorder. Hence, KITE allows the user to select between the two types of disorder by choosing between predefined classes in the python interface. The interface provides two different classes of disorder: * Disorder – onsite disorder with three possible statistical distributions * StructuralDisorder – generic structural disorder, the combination of onsite potential and bond disorder.

Onsite disorder

Disorder adds randomly generated onsite terms at the sites of a desired sublattice based on a certain statistical distribution:

  • Gaussian;
  • Uniform;
  • Deterministic.

Beside the type of statistical distribution, we can select a sublattice type in which the disorder will appear, the mean value and the standard deviation of the selected distribution. To include onsite disorder following a given statistical distribution, we build the lattice and use the following procedure:

disorder = kite.Disorder(lattice) # define an object based on the lattice
disorder.add_disorder('A', 'Gaussian', 0.1, 0.1) # add Gaussian distributed disorder at all sites of a selected sublattice

In a single object it is possible to select multiple sublattices, each of one with different disorder distributions following the rule disorder.add_disorder('sublattice', 'type', mean, std) :

disorder.add_disorder('A', 'Gaussian', 0.1, 0.1)
disorder.add_disorder('B', 'Uniform', 0.2, 0.1)
disorder.add_disorder('C', 'Deterministic', 0.1)

In the case of deterministic disorder, the standard deviation is not set. These quantities are in the same units as the ones specified in the rest of the configuration file.

After defining the desired disorder, it can be added to the configuration file as an additional parameter in the config_system function:

kite.config_system(..., disorder=disorder)

A complete example that calculates the density of states of graphene with different on-site disorder distributions for each sublattice can be seen here:

""" Onsite disorder
Lattice : Monolayer graphene;
Disorder : Disorder class Deterministic and Uniform at different sublattices,
Configuration : size of the system 512×512, without domain decomposition (nx=ny=1), periodic boundary conditions,
double precision, manual scaling;
Calculation : dos;
Modification : magnetic field is off;
"""
import kite
from pybinding.repository import graphene
# load graphene lattice and structural_disorder
lattice = graphene.monolayer()
# add Disorder
disorder = kite.Disorder(lattice)
disorder.add_disorder('B', 'Deterministic', 1.0)
disorder.add_disorder('A', 'Uniform', +1.5, 1.0)
# number of decomposition parts in each direction of matrix.
# This divides the lattice into various sections, each of which is calculated in parallel
nx = ny = 1
# number of unit cells in each direction.
lx = ly = 512
# make config object which caries info about
# – the number of decomposition parts [nx, ny],
# – lengths of structure [lx, ly]
# – boundary conditions, setting True as periodic boundary conditions, and False elsewise,
# – info if the exported hopping and onsite data should be complex,
# – info of the precision of the exported hopping and onsite data, 0 – float, 1 – double, and 2 – long double.
# – scaling, if None it's automatic, if present select spectrum_bound=[e_min, e_max]
configuration = kite.Configuration(divisions=[nx, ny], length=[lx, ly], boundaries=[True, True],
is_complex=False, precision=1)
# require the calculation of DOS
calculation = kite.Calculation(configuration)
calculation.dos(num_points=5000, num_moments=512, num_random=1, num_disorder=1)
# configure the *.h5 file
kite.config_system(lattice, configuration, calculation, modification, 'on_site_disorder.h5', disorder=disorder)

view raw
on_site_disorder.py
hosted with ❤ by GitHub

with the resulting density of states:

image

Structural disorder

StructuralDisorder class adds the possibility of selecting between two different structural disorder types; vacancy, randomly distributed with a certain concentration in sites of a selected sublattice, and a more generic structural disorder which is a combination of onsite terms and bond disorder (also distributed with a certain concentration).

Vacancy disorder

The vacant site distribution can be selected from a single sublattice with a concentration defined in a parent object:

struc_disorder = kite.StructuralDisorder(lattice, concentration=0.2) 

struc_disorder.add_vacancy('B') # add a vacancy to a selected sublattice 

IMPORTANT: to distribute the vacancies in both sublattices, one needs to add the vacancies on each sublattice as a separate object of the class StructuralDisorder (unless you one precisely the same pattern of disorder in both sublatices)

struc_disorder_A = kite.StructuralDisorder(lattice, concentration=0.1)
struc_disorder_A.add_vacancy('A')
struc_disorder_B = kite.StructuralDisorder(lattice, concentration=0.1)
struc_disorder_B.add_vacancy('B')
disorder_structural = [struc_disorder_A, struc_disorder_B]

Structural disorder

Before discussing this class of disorder, it is important to mention that in the pre-release version, it is no possible to perform the automatic scale of the spectra for hopping disorder. In this case, it is necessary to add an extra parameter to the configuration class:

configuration = kite.Configuration(divisions=[nx, ny], length=[lx, ly], boundaries=[True, True],is_complex=False, precision=1,spectrum_range=[-10, 10])

The following example shows a definition of our most general type of disorder, which includes both onsite disorder terms and bond modifications. This type of disorder can be added as an object of the class StructuralDisorder. The procedure for adding the structural disorder is the same of adding a hopping term to the Pybinding lattice object, with a single difference that the bond disorder is not bounded to the hopping term starting from the [0, 0] unit cell, which is the case of the hopping term in pybinding.

For the sake of clarity, let us first define sublattices that will compose the disorder. In this case we are not restricted to a single unit cell:

node0 = [[+0, +0], 'A'] # define a node in a unit cell [i, j] selecting a single sublattice
node1 = [[+0, +0], 'B']
node2 = [[+1, +0], 'A']
node3 = [[+0, +1], 'B']
node4 = [[+0, +1], 'A']
node5 = [[-1, +1], 'B']

After the definition of a parent StructuralDisorder object, we can select the desired pattern:


struc_disorder = kite.StructuralDisorder(lattice, concentration=0.2) # define an object based on the lattice with a certain concentration

struc_disorder.add_structural_disorder(
    # add bond disorder in the form [from unit cell], 'sublattice_from', [to_unit_cell], 'sublattice_to', value:
    (*node0, *node1, 0.5),
    (*node1, *node2, 0.1),
    (*node2, *node3, 0.5),
    (*node3, *node4, 0.3),
    (*node4, *node5, 0.4),
    (*node5, *node0, 0.8),
    # in this way we can add onsite disorder in the form [unit cell], 'sublattice', value
    ([+0, +0], 'B', 0.1)
)
# It is possible to add multiple different disorder types which should be forwarded to the config_system function
# as a list.
another_struc_disorder = kite.StructuralDisorder(lat, concentration=0.6)
another_struc_disorder.add_structural_disorder(
    (*node0, *node1, 0.05),
    (*node4, *node5, 0.4),
    (*node5, *node0, 0.02),
    ([+0, +0], 'A', 0.3)
)

Before exporting the settings to the hdf file, it is possible to define multiple disorder realizations which will be superimposed to the clean system.

The following script has a a minimal example of how to configure the structural disorder

""" Bond disorder
Lattice : Honeycomb 1[nm] interatomic distance and t=1[eV] hopping;
Disorder : StructuralDisorder class bond and vacancy disorder;
Configuration : size of the system 512×512, without domain decomposition (nx=ny=1), periodic boundary conditions,
double precision, manual scaling;
Calculation : dos;
Modification : magnetic field is off;
"""
import numpy as np
import pybinding as pb
import kite
def honeycomb_lattice(onsite=(0, 0)):
"""Make a honeycomb lattice with nearest neighbor hopping"""
theta = np.pi / 3
a1 = np.array([1 + np.cos(theta), np.sin(theta)])
a2 = np.array([0, 2 * np.sin(theta)])
# create a lattice with 2 primitive vectors
lat = pb.Lattice(
a1=a1,
a2=a2
)
# Add sublattices
lat.add_sublattices(
# name, position, and onsite potential
('A', [0, 0], onsite[0]),
('B', [1, 0], onsite[1])
)
# Add hoppings
lat.add_hoppings(
# inside the main cell, between which atoms, and the value
([0, 0], 'A', 'B', 1),
# between neighboring cells, between which atoms, and the value
([1, 0], 'A', 'B', 1),
([1, 1], 'A', 'B', 1),
)
# Add bond disorder as an object of a class StructuralDisorder. In this manner we can add onsite and bond defects
# with a specific concentration, which will be added to the simulated system. The procedure for adding is same
# as adding the hopping, with the difference that the bond disorded is not bounded to one site in the [0, 0]
# unit cell.
node0 = [[+0, +0], 'A']
node1 = [[+0, +0], 'B']
node2 = [[+1, +0], 'A']
node3 = [[+0, +1], 'B']
node4 = [[+0, +1], 'A']
node5 = [[1, +1], 'B']
struc_disorder_one = kite.StructuralDisorder(lat, concentration=0.05)
struc_disorder_one.add_structural_disorder(
# add bond disorder in the form [from unit cell], 'sublattice_from', [to_unit_cell], 'sublattice_to', value:
(*node0, *node1, 1),
(*node1, *node2, 1),
(*node2, *node3, 1),
(*node3, *node4, 1),
(*node4, *node5, 1),
(*node5, *node0, 1),
# in this way we can add onsite disorder in the form [unit cell], 'sublattice', value
([+0, +0], 'B', 0.3)
)
# It is possible to add multiple different disorder type which should be forwarded to the export_lattice function
# as a list.
struc_disorder_two = kite.StructuralDisorder(lat, concentration=0.2)
struc_disorder_two.add_structural_disorder(
(*node0, *node1, 0.4),
(*node4, *node5, 0.4),
(*node5, *node0, 0.4),
([+0, +0], 'B', 0.4)
)
struc_disorder_two.add_vacancy('B')
struc_disorder_three = kite.StructuralDisorder(lat, concentration=0.01)
struc_disorder_three.add_vacancy('A')
# if there is disorder it should be returned separately from the lattice
return lat, [struc_disorder_one, struc_disorder_two, struc_disorder_three]
# load a honeycomb lattice and structural_disorder
lattice, disorder_structural = honeycomb_lattice()
# number of decomposition parts in each direction of matrix.
# This divides the lattice into various sections, each of which is calculated in parallel
nx = ny = 1
# number of unit cells in each direction.
lx = ly = 512
# make config object which caries info about
# – the number of decomposition parts [nx, ny],
# – lengths of structure [lx, ly]
# – boundary conditions, setting True as periodic boundary conditions, and False elsewise,
# – info if the exported hopping and onsite data should be complex,
# – info of the precision of the exported hopping and onsite data, 0 – float, 1 – double, and 2 – long double.
# – scaling, if None it's automatic, if present select spectrum_bound=[e_min, e_max]
configuration = kite.Configuration(divisions=[nx, ny], length=[lx, ly], boundaries=[True, True],
is_complex=False, precision=1, spectrum_range=[15, 15])
# require the calculation of DOS
calculation = kite.Calculation(configuration)
calculation.dos(num_moments=1024, num_random=1, num_disorder=1, num_points=1000)
# configure the *.h5 file
kite.config_system(lattice, configuration, calculation, filename='structural_disorder.h5',
disorder_structural=disorder_structural)

with the resulting density of states

image