Skip to content

Commit 44bf87a

Browse files
committed
Initial commit of ts-tbt-sisl tutorial
This was the tutorial done in November 2016 in Barcelona Signed-off-by: Nick Papior <nickpapior@gmail.com>
0 parents  commit 44bf87a

47 files changed

Lines changed: 27066 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

01/graphene_band_structure.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from __future__ import division
2+
import numpy as np
3+
4+
def create_kpath(Nk):
5+
# Gamma -> K -> M -> Gamma
6+
7+
# Gamma = 0 , 0
8+
# K = 2/3 , 1/3
9+
# M = 1/2 , 1/2
10+
11+
G2K = ( (2./3)**2 + (1./3)**2 ) **.5
12+
K2M = ( (2./3 - 1./2)**2 + (1./3-1./2)**2 ) **.5
13+
M2G = ( (1./2)**2 + (1./2)**2 ) **.5
14+
15+
Kdist = G2K + K2M + M2G
16+
17+
NG2K = int(Nk / Kdist * G2K)
18+
NK2M = int(Nk / Kdist * K2M)
19+
NM2G = int(Nk / Kdist * M2G)
20+
21+
def from_to(N, f, t):
22+
full = np.empty([N, 3])
23+
ls = np.linspace(0, 1, N, endpoint=False)
24+
for i in range(3):
25+
full[:, i] = f[i] + (t[i]-f[i]) * ls
26+
return full
27+
28+
kG2K = from_to(NG2K, [0., 0., 0.], [2./3, 1./3, 0])
29+
kK2M = from_to(NK2M, [2./3, 1./3, 0], [1./2, 1./2, 0.])
30+
kM2G = from_to(NM2G, [1./2, 1./2, 0.], [0., 0., 0.])
31+
32+
xtick = [0, NG2K-1, NG2K + NK2M-1, NG2K + NK2M + NM2G-1]
33+
label = ['G','K', 'M', 'G']
34+
35+
return [xtick, label], np.vstack((kG2K, kK2M, kM2G))
36+
37+
def bandstructure(Nk, H):
38+
39+
ticks, k = create_kpath(Nk)
40+
41+
eigs = np.empty([len(k),2],np.float64)
42+
for ik, k in enumerate(k):
43+
eigs[ik,:] = H.eigh(k=k)
44+
45+
import matplotlib.pyplot as plt
46+
47+
plt.plot(eigs[:,0])
48+
plt.plot(eigs[:,1])
49+
plt.gca().xaxis.set_ticks(ticks[0])
50+
plt.gca().set_xticklabels(ticks[1])
51+
ymin, ymax = plt.gca().get_ylim()
52+
# Also plot x-major lines at the ticks
53+
for tick in ticks[0]:
54+
plt.plot([tick,tick], [ymin,ymax], 'k')
55+
plt.show()
56+
57+
58+
59+
if __name__ == "__main__":
60+
print('This file is intended for use in Hancock_*.py files')
61+
print('It is not intended to be runned separately.')

01/run.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#!/usr/bin/env python
2+
3+
# This tutorial setup the necessary files for running
4+
# a simple graphene system example.
5+
6+
# We will HEAVILY encourage to use Python3 compliant code
7+
# This line ensures the code will run using either Python2 or Python3
8+
from __future__ import print_function
9+
10+
# First we require the use of the sisl Python module.
11+
import sisl
12+
13+
# Instead of manually defining the graphene system we use
14+
# the build-in sisl capability of defining the graphene
15+
# structure.
16+
graphene = sisl.geom.graphene()
17+
18+
# Print out some basic information about the geometry we have
19+
# just created.
20+
print("Graphene geometry information:")
21+
print(graphene)
22+
print()
23+
# It should print that the geometry consists of
24+
# 2 atoms (na)
25+
# 2 orbitals (no), one per atom
26+
# 1 specie (C), both atoms are the same atomic specie
27+
# orbital range of 1.4342 AA (dR)
28+
# 3x3 supercell (nsc), this is determined from dR
29+
30+
# Now as we have the graphene unit-cell, we can create the
31+
# Hamiltonian for the system.
32+
H = sisl.Hamiltonian(graphene)
33+
print("Graphene initial Hamiltonian information:")
34+
print(H)
35+
print()
36+
37+
# Currently this Hamiltonian is an empty entity, i.e.
38+
# no hopping elements has been assigned (all H[i,j] == 0).
39+
# For graphene, one may use these tight-binding parameters:
40+
# on-site: 0. eV
41+
# nearest-neighbour: -2.7 eV
42+
# In the following loop we setup the Hamiltonian with the above
43+
# tight-binding parameters:
44+
for ia, io in H:
45+
# This loop construct loops over all atoms and the orbitals
46+
# corresponding to the atom.
47+
# In this case the geometry has one orbital per atom, hence
48+
# ia == io
49+
# in all cases.
50+
51+
# In order to figure out which atoms atom `ia` is connected
52+
# to, we must find those atoms
53+
# To do this we access the geometry attached to the
54+
# Hamiltonian (H.geom)
55+
# and use a function called `close` which returns ALL
56+
# atoms within certain ranges of a given point or atom
57+
idx = H.geom.close(ia, dR = (0.1, 1.43))
58+
# the argument dR has two entries:
59+
# 0.1 and 1.43
60+
# Each value represents a radii of a sphere.
61+
# The `close` function will then return
62+
# a list of equal length of the dR argument (i.e. a list with
63+
# two values).
64+
# Then idx[0] is the first element and this contains a list
65+
# of all atoms within a sphere of 0.1 AA of atom `ia`.
66+
# This should obviously only contain the atom it-self.
67+
# The second element, idx[1] contains all atoms within a sphere
68+
# with radius of 1.43 AA, but not including those within 0.1 AA.
69+
# In this case this is then all atoms that are the nearest neighbour
70+
# atoms
71+
72+
# Now we know the on-site atoms (idx[0]) and the nearest neighbour
73+
# atoms (idx[1]), all we need to do is set the Hamiltonian
74+
# elements:
75+
76+
# on-site (0. eV)
77+
H[io, idx[0]] = 0.
78+
79+
# nearest-neighbour (-2.7 eV)
80+
H[io, idx[1]] = -2.7
81+
82+
# At this point we have created all Hamiltonian elements for all orbitals
83+
# in the graphene geometry.
84+
# Let's try and print the information of the Hamiltonian object:
85+
print("Hamiltonian after setting up the parameters:")
86+
print(H)
87+
print()
88+
# It now prints that there are 8 non-zero elements.
89+
# Please convince yourself that this is the correct number of
90+
# Hamiltonian elements (regard the on-site value of 0. eV as a non-zero
91+
# value). HINT: count the number of on-site and nearest-neighbour terms)
92+
93+
# At this point we have all the ingredients for manipulating the electronic
94+
# structure of graphene in a tight-binding model with nearest neighbour
95+
# interactions.
96+
97+
# We may, for instance, calculate the eigen-spectrum at the Gamma-point:
98+
print("Eigenvalues at Gamma:")
99+
print(H.eigh())
100+
print("Eigenvalues at K:")
101+
print(H.eigh(k=[1./3,2./3,0]))
102+
print()
103+
104+
# Additionally we may calculate the band-structure of graphene
105+
# We want to plot the band-structure of graphene
106+
107+
from graphene_band_structure import bandstructure
108+
109+
# Now lets plot the band-structure (requires matplotlib)
110+
bandstructure(301, H)
111+

02/RUN.fdf

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Define the device Hamiltonian
2+
TBT.HS DEVICE.nc
3+
4+
# Graphene requires a high k-point sampling
5+
# Try and play with this number to find
6+
# a value which gives a smooth
7+
# integration.
8+
# Please note which unit-cell direction
9+
# that the below array defines
10+
TBT.k [50 1 1]
11+
12+
# These are the definitions of the electrodes
13+
# They may seem very verbose, but this
14+
# gives the user a very high degree of
15+
# flexibility. This will be apparent
16+
# in later tutorials
17+
%block TBT.Elec.Left
18+
# Define the electronic structure
19+
# of the electrode
20+
HS ELEC.nc
21+
22+
# The semi-infinite direction was
23+
# along the second lattice vector (A2)
24+
# The negative sign is to specify
25+
# the direction of the semi-infinite
26+
# bulk part
27+
semi-inf-direction -A2
28+
29+
# Denote the first atom of the electrode.
30+
# This index corresponds to the atomic
31+
# index in the TBT.HS file
32+
electrode-position 1
33+
%endblock TBT.Elec.Left
34+
35+
# Also define the equivalent quantities
36+
# for the right electrode
37+
%block TBT.Elec.Right
38+
HS ELEC.nc
39+
# The system is <- Left | device | Right ->
40+
# hence the semi-infinite direction of the Right
41+
# electrode has +
42+
semi-inf-direction +A2
43+
# Note the use of "end" which
44+
# refers to the last atom of the electrode
45+
electrode-position end -1
46+
%endblock TBT.Elec.Right

02/run.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env python
2+
3+
import sisl
4+
5+
# Instead of manually defining the graphene system we use
6+
# the build-in sisl capability of defining the graphene
7+
# structure.
8+
# Note that this graphene unit-cell is an orthogonal unit-cell
9+
# (figure out how many atoms this consists off)
10+
graphene = sisl.geom.graphene(orthogonal=True)
11+
12+
# Now as we have the graphene unit-cell, we can create the
13+
# Hamiltonian for the system.
14+
H = sisl.Hamiltonian(graphene)
15+
16+
# Instead of using the for-loop provided in 01, we
17+
# may use a simpler function that *ONLY* works
18+
# for 1-orbital per atom models.
19+
H.construct([0.1, 1.43], [0., -2.7])
20+
21+
# At this point we have created all Hamiltonian elements for all orbitals
22+
# in the graphene geometry.
23+
# Please try and figure out how many non-zero elements there should
24+
# be in the Hamiltonian object.
25+
# HINT: count the number of on-site and nearest-neighbour terms
26+
27+
# Now we have the Hamiltonian, now we need to save it to be able
28+
# to conduct a tbtrans calculation:
29+
# As this is the minimal unit-cell we call this the electrode
30+
# and we will in the following create a larger "DEVICE" region
31+
# Hamiltonian.
32+
H.write('ELEC.nc')
33+
34+
# Now we need to create the device region Hamiltonian.
35+
# The tbtrans method relies on including the electrodes
36+
# in the device region. Hence the smallest device region
37+
# must be 3 times the electrode size.
38+
# Please try and convince your-self that this is the case.
39+
# HINT: consider the interaction range of the atoms
40+
41+
# We tile the geometry along the 2nd lattice vector
42+
# (Python is 0-based indexing)
43+
device = graphene.tile(3, axis=1)
44+
Hdev = sisl.Hamiltonian(device)
45+
Hdev.construct([0.1, 1.43], [0, -2.7])
46+
# We will create both a xyz file (for plotting in molden, etc.)
47+
# and we will create the Hamilton file format for reading in tbtrans
48+
Hdev.geom.write('device.xyz')
49+
Hdev.write('DEVICE.nc')
50+

03/RUN.fdf

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Define the device Hamiltonian
2+
TBT.HS DEVICE.nc
3+
4+
# Graphene requires a high k-point sampling
5+
# Try and play with this number to find
6+
# a value which gives a smooth
7+
# integration.
8+
TBT.k [50 1 1]
9+
10+
# These are the definitions of the electrodes
11+
# They may seem very verbose, but this
12+
# gives the user a very high degree of
13+
# flexibility. This will be apparent
14+
# in later tutorials
15+
%block TBT.Elec.Left
16+
HS ELEC.nc
17+
# The semi-infinite direction was
18+
# along the second lattice vector (A2)
19+
# The negative sign is to specify
20+
# the direction of the semi-infinite
21+
# bulk part
22+
semi-inf-direction -A2
23+
electrode-position 1
24+
%endblock TBT.Elec.Left
25+
26+
%block TBT.Elec.Right
27+
HS ELEC.nc
28+
semi-inf-direction +A2
29+
electrode-position end -1
30+
%endblock TBT.Elec.Right

03/run.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env python
2+
3+
import sisl
4+
5+
# Instead of manually defining the graphene system we use
6+
# the build-in sisl capability of defining the graphene
7+
# structure.
8+
# (figure out how many atoms this consists off)
9+
graphene = sisl.geom.graphene().tile(2, axis=0)
10+
11+
# Now as we have the graphene unit-cell, we can create the
12+
# Hamiltonian for the system.
13+
H = sisl.Hamiltonian(graphene)
14+
15+
# Instead of using the for-loop provided in 01, we
16+
# may use a simpler function that *ONLY* works
17+
# for 1-orbital per atom models.
18+
H.construct([0.1, 1.43], [0., -2.7])
19+
20+
# At this point we have created all Hamiltonian elements for all orbitals
21+
# in the graphene geometry.
22+
# Please try and figure out how many non-zero elements there should
23+
# be in the Hamiltonian object.
24+
# HINT: count the number of on-site and nearest-neighbour terms
25+
26+
# Now we have the Hamiltonian, now we need to save it to be able
27+
# to conduct a tbtrans calculation:
28+
# As this is the minimal unit-cell we call this the electrode
29+
# and we will in the following create a larger "DEVICE" region
30+
# Hamiltonian.
31+
H.write('ELEC.nc')
32+
33+
# Now we need to create the device region Hamiltonian.
34+
# The tbtrans method relies on including the electrodes
35+
# in the device region. Hence the smallest device region
36+
# must be a multiple of 3 of the electrode size.
37+
# Please try and convince your-self that this is the case.
38+
# HINT: consider the interaction range of the atoms
39+
40+
# We tile the geometry along the 2nd lattice vector
41+
# (Python is 0-based indexing)
42+
device = graphene.tile(3, axis=1)
43+
Hdev = sisl.Hamiltonian(device)
44+
Hdev.construct([0.1, 1.43], [0, -2.7])
45+
# We will create both a xyz file (for plotting in molden, etc.)
46+
# and we will create the Hamilton file format for reading in tbtrans
47+
Hdev.geom.write('device.xyz')
48+
Hdev.write('DEVICE.nc')
49+

04/RUN.fdf

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
TBT.HS DEVICE.nc
2+
3+
# This is also a transverse periodic system and
4+
# again the k-mesh is important for converged results.
5+
TBT.k [5 1 1]
6+
7+
# Define which physical quantites to calculate.
8+
# Each of these flags will decide what to calculate
9+
# in the calculation.
10+
# If you look these flags up in the manual you will
11+
# find the physical quantities they correspond to.
12+
TBT.DOS.Gf true
13+
TBT.DOS.Elecs true
14+
TBT.DOS.A true
15+
TBT.DOS.A.All true
16+
TBT.T.All true
17+
TBT.T.Bulk true
18+
TBT.T.Eig 5
19+
TBT.Current.Orb true
20+
TBT.Symmetry.TimeReversal false
21+
22+
23+
%block TBT.Elec.Left
24+
HS ELEC.nc
25+
semi-inf-direction -A2
26+
electrode-position 1
27+
%endblock TBT.Elec.Left
28+
%block TBT.Elec.Right
29+
HS ELEC.nc
30+
semi-inf-direction +A2
31+
electrode-position end -1
32+
%endblock TBT.Elec.Right

0 commit comments

Comments
 (0)