# 6. 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 1. Lattice, 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:

### Onsite disorder¶

kite.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 pb.lattice and use the following procedure:

# define an object based on the lattice
disorder = kite.Disorder(lattice)
# 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 kite.Disorder.add_disorder('sublattice', 'type', mean, std) :

disorder.add_disorder('A', 'Gaussian', 0.1, 0.1)


In the case of deterministic disorder, the standard deviation is not set.

After defining the desired disorder, it can be added to the configuration file as an additional parameter in the kite.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:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 import kite from pybinding.repository import graphene """ 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, automatic scaling; Calculation : dos; Modification : magnetic field is off; """ # 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 [nx,ny] in each direction of matrix. # This divides the lattice into various sections, each of which is calculated in parallel nx = ny = 2 # 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 [mode,mode, ... ] with modes: # . "periodic" # . "open" # . "twisted" -- this option needs the extra argument angles # . "random" # Boundary Mode mode = "periodic" configuration = kite.Configuration( divisions=[nx, ny], length=[lx, ly], boundaries=[mode, mode], 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, filename='on_site_disorder.h5', disorder=disorder) 

### Structural disorder¶

kite.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)


Note

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

struc_disorder_A = kite.StructuralDisorder(lattice, concentration=0.1)
struc_disorder_B = kite.StructuralDisorder(lattice, concentration=0.1)
disorder_structural = [struc_disorder_A, struc_disorder_B]


#### Structural disorder¶

To manyally set the spectrum_range, it is necessary to add an extra parameter to the kite.Configuration class:

configuration = kite.Configuration(
divisions=[nx, ny],
length=[lx, ly],
boundaries=["periodic", "periodic"],
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 kite.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:

#  define a node in a unit cell [i, j] selecting a single sublattice
node0 = [[+0, +0], 'A']
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 kite.StructuralDisorder object, we can select the desired pattern:

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

# 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)
(*node0, *node1, 0.05),
(*node4, *node5, 0.4),
(*node5, *node0, 0.02),
([+0, +0], 'A', 0.3)
)


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

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

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 """ 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 512x512, 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: