Skip to content

Commit c0806b8

Browse files
committed
Revert change of Hamiltonian phase sign cf. #105
- while doing this, also correct the direction shown for the hopping in the tight-binding model visualization to align with actual electron hopping direction
1 parent 02015f8 commit c0806b8

7 files changed

Lines changed: 34 additions & 63 deletions

File tree

ext/SymmetricTightBindingMakieExt.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,19 +194,21 @@ _cubic_basis(::Val{1}) = crystal(1)
194194
_cubic_basis(::Val{D}) where {D} = error("Unsupported dimension: $D")
195195
## --------------------------------------------------------------------------------------- #
196196

197-
# simple case: take no account of a coefficient vector, just plot all hoppings in `h`
197+
# Simple case: take no account of a coefficient vector, just plot all hoppings in `h`.
198+
# The hopping `δ` is such that `δ = b+R-a`, so the hopping direction is from `b+R`
199+
# (annihilated) to `a` (created).
198200
function _origins_and_destinations_from_hoppingorbit(
199201
h::HoppingOrbit{D},
200202
Rm::AbstractMatrix{<:Real}
201203
) where D
202204
P = Point{D, Float32}
203-
origins = mapreduce(vcat, h.hoppings) do hs
205+
destinations = mapreduce(vcat, h.hoppings) do hs
204206
map(hs) do h
205207
a = Rm * constant(h[1])
206208
P(a)
207209
end
208210
end
209-
destinations = mapreduce(vcat, h.hoppings) do hs
211+
origins = mapreduce(vcat, h.hoppings) do hs
210212
map(hs) do h
211213
b_plus_R = Rm * (constant(h[2]) + constant(h[3]))
212214
P(b_plus_R)
@@ -244,8 +246,8 @@ function _origins_and_destinations_from_coefficients(
244246
has_hop || continue
245247
a = P(Rm * constant(h[1]))
246248
b_plus_R = P(Rm * (constant(h[2]) + constant(h[3])))
247-
push!(origins, a)
248-
push!(destinations, b_plus_R)
249+
push!(destinations, a)
250+
push!(origins, b_plus_R)
249251
end
250252
end
251253
return origins, destinations

src/gradients.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ function evaluate_tight_binding_momentum_gradient_term!(
232232
# NB: ↓ one more case of assuming no free parameters in
233233
# `δs = constant.(orbit(block.h_orbit))` (we don't materialize `δs` though)
234234
δs = orbit(block.h_orbit)
235-
v_conj = cispi.(dot.(Ref(2 .* k), constant.(δs)))
235+
v_conj = cispi.(dot.(Ref(-2 .* k), constant.(δs)))
236236
δ_mult_v_conj = similar(v_conj) # preallocate for reuse below
237237
for (idx, component) in enumerate(components)
238238
∇H = ∇Hs[idx]
@@ -243,7 +243,7 @@ function evaluate_tight_binding_momentum_gradient_term!(
243243
for (local_i, i) in enumerate(is)
244244
for (local_j, j) in enumerate(js)
245245
∇Hᵢⱼ = @inbounds dot(δ_mult_v_conj, @view MmtC[:, local_i, local_j])
246-
∇Hᵢⱼ *= -2im * π # (-2πi) factor from ∂/∂kᵢ of e^{-2πik·δ}
246+
∇Hᵢⱼ *= 2im * π # (-2πi) factor from ∂/∂kᵢ of e^{-2πik·δ}
247247
isnothing(c) || (∇Hᵢⱼ *= c) # multiply by coefficient if provided
248248
∇H[i, j] += ∇Hᵢⱼ
249249
i == j && continue # don't add diagonal elements twice

src/tightbinding.jl

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ WP of `brᵦ`, displaced by a set of primitive lattice-vector representatives `R
1111
1212
## Implementation
1313
1. Take a point `a` in the WP of `brₐ` and a point `b` in the WP of `brᵦ`.
14-
Compute the displacement vector `δ = b + R - a`, where `R ∈ Rs`.
14+
Compute the displacement vector `δ = b + R - a`, where `R ∈ Rs`, giving the displacement
15+
vector from `a` (created site) to `b + R` (annihilated site): i.e., `δ` points opposite
16+
to the hopping direction.
1517
2. If `δ ∈ representatives`, add `δ => (a, b, R)` to the list of hoppings
1618
for that representative and continue. Otherwise, search all representatives for one
1719
whose list of hoppings contains `δ => (a, b, R)`. If none is found, add `δ` as a new
@@ -218,14 +220,14 @@ function add_reversed_orbits!(h_orbits::Vector{HoppingOrbit{D}}) where {D}
218220
deleteat!(h_orbits, n′)
219221
continue
220222
end
221-
# we now know that at least some δ doesn't have a -δ counterpart; we assume that
222-
# this implies that none of the δs have a -δ counterpart, so we need to add them all
223+
# we now know that at least some δ doesn't have a -δ counterpart; we assume that
224+
# this implies that none of the δs have a -δ counterpart, so we need to add them all
223225
@assert all-> !isapproxin(-δ, δs, nothing, false; atol = VEC_CMP_ATOL), δs)
224226

225227
# first append the new δs into the orbit
226228
append!(δs, -δs)
227229

228-
# add the "reversed" hopping terms: i.e., for every a → b + R, add b + R → a
230+
# add the "reversed" hopping terms: i.e., for every a → b + R, add b + R → a
229231
# => -δ = a - (b + R) = a - b - R = b - 2b - R -a + 2a = b + (2a - 2b - R) - a = b + R' - a
230232
hoppings = h_orbit.hoppings
231233
hoppings′ = map(hoppings) do hops
@@ -238,35 +240,6 @@ function add_reversed_orbits!(h_orbits::Vector{HoppingOrbit{D}}) where {D}
238240
end
239241

240242
# ---------------------------------------------------------------------------- #
241-
# EBRs: (q|A), (w|B)
242-
# Wyckoff positions: q, w
243-
# q: q1, ..., qN
244-
# w: w1, ..., wM
245-
# Site symmetry irreps: A, B
246-
# A: A1, ..., AJ
247-
# B: B1, ..., BK
248-
# δs = [δ1, δ2, ..., δn]
249-
# δ1: qi₁¹ -> wj₁¹, qi₁² -> wj₁², ...
250-
# δ2: qi₂¹ -> wj₂¹, qi₂² -> wj₂², ...
251-
# v = [exp(-ik⋅δ1), exp(-ik⋅δ2), ..., exp(-ik⋅δn)]
252-
# t = [[t(δ1) ...], [t(δ2) ...], ..., [t(δn) ...]]
253-
# t(δ1): [t(qi₁ᵅ -> wj₁ᵅ, A_f -> B_g) ...]
254-
255-
# Current example: (1a|E), (2c|A)
256-
# ___w2__
257-
# | x |
258-
# |q1 x x w1
259-
# |_______|
260-
# δs = [1/2x, -1/2x, 1/2y, -1/2y]
261-
# δ1: q1 -> w1 + G1
262-
# δ2: q1 -> w1 + G2
263-
# δ3: q1 -> w2 + G3
264-
# δ4: q1 -> w2 + G4
265-
# t = [t(δ1)..., t(δ2)..., t(δ3)..., t(δ4)...]
266-
# t(δ1): [t(q1 -> w1, G1, E1 -> A1), t(q1 -> w1, G1, E2 -> A1)]
267-
# t(δ2): [t(q1 -> w1, G2, E1 -> A1), t(q1 -> w1, G2, E2 -> A1)]
268-
# t(δ3): [t(q1 -> w2, G3, E1 -> A1), t(q1 -> w2, G3, E2 -> A1)]
269-
# t(δ4): [t(q1 -> w2, G4, E1 -> A1), t(q1 -> w2, G4, E2 -> A1)]
270243

271244
# NB: The ordering of `t` is a bit subtle: `t` is a kind of vector-flattened
272245
# tensor `T`, with the following "indexing convention" for `T`:
@@ -420,8 +393,6 @@ function construct_M_matrix(
420393
return Mm
421394
end
422395

423-
# H_{s,t} = v_i M_{i,j,s,t} t_j
424-
425396
"""
426397
representation_constraints_matrices(
427398
Mm::AbstractArray{Int,4},
@@ -749,7 +720,7 @@ Build the P matrix for a particular symmetry operation acting on k-space, which
749720
rows of the M matrix.
750721
751722
To obtain the P matrix, we exploit that the action is on exponentials of the type
752-
``exp(-2πi𝐤⋅δ)``, and instead act on δ ∈ `h_orbit.orbit` rather than on k. Because of this,
723+
``exp(2πi𝐤⋅δ)``, and instead act on δ ∈ `h_orbit.orbit` rather than on k. Because of this,
753724
we need to use the inverse of the rotation part of the symmetry operation.
754725
755726
!!! details "Sketch of proof"

src/types.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ function _getindex(
221221
if !iszero(δ) # print the exponential: our notation is 𝕖(δ) ≡ exp(2πi𝐤⋅δ)
222222
print(io, "𝕖(")
223223
# TODO: could do a little better here, since we know that `-δ` is in the orbit?
224-
conjugate || print(io, "-")
224+
conjugate && print(io, "-")
225225
print(io, "δ", Crystalline.subscriptify(string(n)), ")")
226226
else
227227
print(io, "1")
@@ -416,14 +416,14 @@ function evaluate_tight_binding_term!(
416416
MmtC = block.MmtC # contracted product of `Mm` and (complexified) `t`
417417

418418
# NB: ↓ one more case of assuming no free parameters in `δ`
419-
v_conj = cispi.(dot.(Ref(2 .* k), constant.(orbit(block.h_orbit))))
419+
v_conj = cispi.(dot.(Ref(-2 .* k), constant.(orbit(block.h_orbit))))
420420
# NB: ↑ this is `v` conjugated: we do this because the `dot`-product below conjugates
421421
# its first argument; so by conjugating twice we get the unconjugated result.
422422
# NB: ↑ each term in the Hamiltonian is associated to an annihilation+creation operator
423423
# pair `aᵢ† aⱼ`. Since we use Convention 1 for the Fourier transform, we have
424-
# aᵢ† = ∑ₖ e^{-ik·(tᵢ + rᵢ)} aₖ†, such that each term will be multiplied by a phase
425-
# e^{-ik·δᵢⱼ} with δᵢⱼ ≡ Rᵢⱼ + rᵢ - rⱼ, i.e., the hopping vector in the orbit; this
426-
# is what `orbit(block.h_orbit)` gives us above
424+
# aᵢ† = √N⁻¹ ∑ₖ e^{-ik·(tᵢ + rᵢ)} aₖ†, such that each term will be multiplied by a
425+
# phase e^{ik·δᵢⱼ} with δᵢⱼ ≡ Rᵢⱼ + rᵢ - rⱼ, i.e., the hopping vector in the orbit;
426+
# this is what `orbit(block.h_orbit)` gives us above
427427
for (local_i, i) in enumerate(is)
428428
for (local_j, j) in enumerate(js)
429429
Hᵢⱼ = @inbounds dot(v_conj, @view MmtC[:, local_i, local_j])

test/berry.jl

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ end
120120
kc = cartesianize(k, dualbasis(directbasis(13, Val(2))))
121121

122122
H = (
123-
t₁ * (cos(dot(kc, a₁)) + cos(dot(kc, a₂)) + cos(dot(kc, a₃))) .* [0 1; 1 0] +
124-
t₁ * (sin(dot(kc, a₁)) + sin(dot(kc, a₂)) + sin(dot(kc, a₃))) .* [0 -1im; 1im 0] +
125-
2 * t₂* cos(ϕ) * (cos(dot(kc, b₁)) + cos(dot(kc, b₂)) + cos(dot(kc, b₃))) .* [1 0; 0 1] +
126-
2 * t₂* sin(ϕ) * (sin(dot(kc, b₁)) + sin(dot(kc, b₂)) + sin(dot(kc, b₃))) .* [1 0; 0 -1] +
123+
t₁ * (cos(kc a₁) + cos(kc a₂) + cos(kc a₃)) .* [0 1; 1 0] +
124+
t₁ * (sin(kc a₁) + sin(kc a₂) + sin(kc a₃)) .* [0 -1im; 1im 0] +
125+
2t₂ * cos(ϕ) * (cos(kc b₁) + cos(kc b₂) + cos(kc b₃)) .* [1 0; 0 1] +
126+
2t₂ * sin(ϕ) * (sin(kc b₁) + sin(kc b₂) + sin(kc b₃)) .* [1 0; 0 -1] +
127127
m .* [1 0; 0 -1]
128128
)
129129
return H
@@ -136,9 +136,7 @@ end
136136
H_ptbm = haldane_model(t₁, m, t₂, ϕ)(k)
137137
H_original = manual_haldane_model(k, t₁, m, t₂, ϕ)
138138

139-
# TODO: the hardcoded coefficients in `manual_haldane_model` use the old
140-
# Hamiltonian phase convention; update after correcting (cf. PR #89)
141-
@test_broken isapprox(H_ptbm, H_original)
139+
@test isapprox(H_ptbm, H_original)
142140
end
143141

144142
# test that we also get the right Chern numbers

test/show.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ test_tp_show(v, expected::AbstractString) = test_show(repr(MIME"text/plain"(), v
5757

5858
str = """
5959
2×2 TightBindingTerm{2} over [(2b|A₁)]:
60-
0 𝕖(-δ₄)+𝕖(-δ₅)+𝕖(-δ₆)
61-
𝕖(-δ₁)+𝕖(-δ₂)+𝕖(-δ₃) 0
60+
0 𝕖(δ₄)+𝕖(δ₅)+𝕖(δ₆)
61+
𝕖(δ₁)+𝕖(δ₂)+𝕖(δ₃) 0
6262
δ₁=[-1/3,1/3], δ₂=[-1/3,-2/3], δ₃=[2/3,1/3], δ₄=-δ₁, δ₅=-δ₂, δ₆=-δ₃"""
6363
test_tp_show(tbm[2], str)
6464
end
@@ -71,8 +71,8 @@ test_tp_show(v, expected::AbstractString) = test_show(repr(MIME"text/plain"(), v
7171
│ ⎣ 0 1 ⎦
7272
└─ (2b|A₁) self-term
7373
┌─
74-
2. ⎡ 0 𝕖(-δ₄)+𝕖(-δ₅)+𝕖(-δ₆) ⎤
75-
│ ⎣ 𝕖(-δ₁)+𝕖(-δ₂)+𝕖(-δ₃) 0
74+
2. ⎡ 0 𝕖(δ₄)+𝕖(δ₅)+𝕖(δ₆) ⎤
75+
│ ⎣ 𝕖(δ₁)+𝕖(δ₂)+𝕖(δ₃) 0 ⎦
7676
└─ (2b|A₁) self-term: δ₁=[-1/3,1/3], δ₂=[-1/3,-2/3], δ₃=[2/3,1/3], δ₄=-δ₁, δ₅=-δ₂, δ₆=-δ₃"""
7777
test_tp_show(tbm, str)
7878
end

test/symmetry_analysis.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ end
4141
# topological EBRs): i.e., we don't know if the model is a single connected band or not,
4242
# only what the "sum" of symmetry vectors will be.
4343

44-
function _test_symmetry_analysis(brs, i, αβγ; rng_seed=1234)
44+
function _test_symmetry_analysis(brs, i, αβγ; rng = seed!(copy(Random.default_rng()), 1234))
4545
coefs = zeros(length(brs))
4646
coefs[i] = 1
4747
cbr = CompositeBandRep(coefs, brs)
4848
iszero(free(position(brs[i]))) || pin_free!(brs, i => αβγ)
4949
tbm = tb_hamiltonian(cbr)
50-
rng = seed!(copy(Random.default_rng()), rng_seed)
5150
ptbm = tbm(randn(rng, length(tbm)))
5251
ns = collect_compatible(ptbm)
53-
return !isempty(ns) && sum(ns) == SymmetryVector(cbr)
52+
@test !isempty(ns)
53+
@test sum(ns) == SymmetryVector(cbr)
5454
end
5555

5656
@testset "Symmetry analysis (full scan over EBRs)" begin
@@ -60,7 +60,7 @@ end
6060
@testset "Space group $sgnum in dimension $D" begin
6161
brs = calc_bandreps(sgnum, Val(D))
6262
for i in eachindex(brs)
63-
@test _test_symmetry_analysis(brs, i, αβγ)
63+
_test_symmetry_analysis(brs, i, αβγ)
6464
end
6565
end
6666
end

0 commit comments

Comments
 (0)