Skip to content

Commit 9249751

Browse files
committed
kubo formula chern number
1 parent a0b0bdb commit 9249751

File tree

1 file changed

+60
-15
lines changed

1 file changed

+60
-15
lines changed

src/Chern.jl

+60-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
module Chern
2-
export FindLinks , FieldStrength , ChernNumber, CheckValidity, PartialChernNumber, FilledChernNumber
2+
export FindLinks , FieldStrength , ChernNumber, CheckValidity, PartialChernNumber, FilledChernNumber, OccupiedChernNumber, KuboChern
33

4-
using ..TightBindingToolkit.Hams:Hamiltonian, IsBandGapped
4+
using ..TightBindingToolkit.Hams:Hamiltonian, IsBandGapped, GetVelocity!
5+
using ..TightBindingToolkit.Useful: DistFunction
6+
using ..TightBindingToolkit.BZone:BZ
57

68
using LinearAlgebra
79

@@ -21,7 +23,7 @@ On a bond connecting k_i and k_j, the linking matrix U is defined such that U[m,
2123
Link_1 = det.(selectdim.(adjoint.(Ham.states), 1, Ref(subset)) .* selectdim.(shifted_1, 2, Ref(subset)))
2224
Link_2 = det.(selectdim.(adjoint.(Ham.states), 1, Ref(subset)) .* selectdim.(shifted_2, 2, Ref(subset)))
2325
##### selectdim(x, 1, v) = x[v, :] and similarly selectdim(x, 2, v) = x[:, v]
24-
##### selectdim.(M, 1, Ref(subset)) ---> [[M[subset, :] for all k points]]
26+
##### selectdim.(M, 1, Ref(subset)) ---> [[M[subset, :] for all k points]]
2527
return (Link_1, Link_2)
2628
end
2729

@@ -91,18 +93,18 @@ PartialChernNumber(Ham::Hamiltonian, band::Int64, mu::Float64) --> Float64
9193
Function to get the Chern number of a partially filled band given a `Hamiltonian`, a `band` index, and a chemical potential `mu`.
9294
9395
"""
94-
function PartialChernNumber(Ham::Hamiltonian, band::Int64, mu::Float64)::Float64
95-
96+
function PartialChernNumber(Ham::Hamiltonian, band::Int64, mu::Float64, T::Float64)::Float64
97+
9698
@assert band in UnitRange(1, length(Ham.bands[begin])) "Band index out of range!"
9799

98100
Links = FindLinks(Ham, [band])
99101
Field = FieldStrength(Links)
100102

101103
energies= getindex.(Ham.bands, Ref(band))
102-
filled = (energies .< mu)
104+
filled = DistFunction(energies; mu = mu, T = T, stat = -1)
103105
chern = (1/(2*pi)) * sum((angle.(Field)) .* filled )
104106

105-
return chern
107+
return chern
106108
end
107109

108110

@@ -112,21 +114,64 @@ FilledChernNumber(Ham::Hamiltonian, mu::Float64) --> Float64
112114
Function to get the Chern number of bands filled upto a given chemical potential `mu`.
113115
114116
"""
115-
function FilledChernNumber(Ham::Hamiltonian, mu::Float64)::Float64
117+
function FilledChernNumber(Ham::Hamiltonian, mu::Float64, T::Float64)::Float64
118+
119+
# filled_bands = searchsortedfirst.(Ham.bands, Ref(mu)) .- 1
120+
121+
# if findmax(filled_bands)[1] == 0
122+
# @warn "Chemical potential is below the lowest band. Chern number is not well defined!"
123+
# return 0.0
116124

117-
filled_bands = searchsortedfirst.(Ham.bands, Ref(mu)) .- 1
125+
# else
126+
return sum(PartialChernNumber.(Ref(Ham), collect(1:length(Ham.bands[begin])), Ref(mu), Ref(T)))
127+
# end
118128

119-
if findmax(filled_bands)[1] == 0
120-
@warn "Chemical potential is below the lowest band. Chern number is not well defined!"
121-
return 0.0
129+
end
130+
131+
function OccupiedChernNumber(Ham::Hamiltonian, mu::Float64, T::Float64)
132+
chern = 0.0
122133

123-
else
124-
return sum(PartialChernNumber.(Ref(Ham), collect(1:findmax(filled_bands)[1]), Ref(mu)))
134+
for band in 1:length(Ham.bands[begin])
135+
link = FindLinks(Ham, [band])
136+
field = FieldStrength(link)
137+
occupation = DistFunction(getindex.(Ham.bands, band); mu = mu, T = T)
138+
chern += (1/(2*pi)) * sum((angle.(field)) .* occupation)
125139
end
126140

141+
return chern
127142
end
128143

144+
function KuboChern(Ham::Hamiltonian, bz::BZ, mu::Float64)
145+
146+
Vx = conj.(permutedims.(Ham.states)) .* Ham.velocity[1] .* Ham.states
147+
Vy = conj.(permutedims.(Ham.states)) .* Ham.velocity[2] .* Ham.states
129148

149+
chern = 0.0 + im*0.0
150+
for k in eachindex(Ham.bands)
151+
Es = Ham.bands[k]
152+
vx = Vx[k]
153+
vy = Vy[k]
154+
155+
ind = searchsortedfirst(Es, mu)
156+
if ind == 1 || ind == length(Es)
157+
continue
158+
else
159+
for i in 1:ind-1
160+
for j in ind:length(Es)
161+
chern += (vx[i, j] * vy[j, i] - vx[j, i] * vy[i, j]) / ((Es[j] - Es[i])^2)
162+
end
163+
end
164+
end
165+
166+
end
167+
168+
b1 = [bz.basis[1];0.0]
169+
b2 = [bz.basis[2];0.0]
170+
bzUnitArea = cross(b1, b2)[3]/(4*pi^2)
171+
172+
return imag(chern)*bzUnitArea*2*pi/length(Ham.bands)
173+
174+
end
130175

131176

132-
end
177+
end

0 commit comments

Comments
 (0)