Skip to content

Commit ecc22df

Browse files
committed
update nonhermitian docs
1 parent a2185f6 commit ecc22df

1 file changed

Lines changed: 270 additions & 22 deletions

File tree

docs/src/nonhermitian.md

Lines changed: 270 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,54 +9,302 @@ It is simple to build this model with SymmetricTightBinding.jl:
99

1010
```@example hatano-nelson
1111
using Crystalline, SymmetricTightBinding
12-
brs = calc_bandreps(1, 1) # EBRs in plane group 1, with time-reversal symmetry
13-
pin_free!(brs, [1=>[0]]) # the 1a Wyckoff position in plane group 1 has a free parameter: set to 0 for definiteness
14-
cbr = @composite brs[1] # single-site model
12+
brs = calc_bandreps(1, 1) # EBRs in plane group 1, with time-reversal symmetry
13+
pin_free!(brs, [1=>[0]]) # the 1a Wyckoff position in plane group 1 has a free parameter: set to 0 for definiteness
14+
cbr = @composite brs[1] # single-site model
1515
tbm = tb_hamiltonian(cbr, [[1]], NONHERMITIAN) # nearest neighbor hoppings
1616
```
1717

18-
The model is very simple: two different hopping terms, corresponding to right- and left-directed hopping terms. The absence of hermiticity allows the hopping amplitudes in either direction to differ, contrasting the Hermitian case:
18+
The model is very simple: two different hopping terms, corresponding to right- and left-directed hops.
19+
It is the absence of hermiticity that allows the hopping amplitudes to differ in the two directions, in clear contrast to the Hermitian case:
1920

2021
```@example hatano-nelson
2122
tb_hamiltonian(cbr, [[1]], HERMITIAN)
2223
```
23-
The non-Hermitian model reduces to the Hermitian model when the left- and right-directed hopping amplitudes are equal. When the two are _not_ equal, the Hatano-Nelson model features exceptional points and spontaneous symmetry breaking of the real spectrum, as we can verify by example (using Brillouin.jl and GLMakie.jl for dispersion plotting):
2424

25-
```@example hatano-nelson
26-
ptbm = tbm([0.9, 1.1]) # a model with 0.9 hopping amplitude to right, 1.1 to the left
25+
Of course, the non-Hermitian model reduces to the Hermitian model when the left- and right-directed hopping amplitudes are equal.
26+
However, when the two amplitudes are unequal, the Hatano--Nelson model features nontrivial spectral winding in the sense that its spectrum traces out a finite-area spectral loop in the complex plane as its momentum is varied across one loop.
27+
We can see this by visualizing the complex energy as we vary $k$ from -1/2 to 1/2:
2728

28-
using Brillouin
29-
kp = irrfbz_path(1, directbasis(1, 1)) # a k-path in plane group 1
30-
kpi = interpolate(kp, 500) # interpolated over 500 points
31-
Es = spectrum(ptbm, kpi)
32-
Es_re = sort(real.(Es); dims=2)
33-
Es_im = sort(imag.(Es); dims=2)
29+
```@example hatano-nelson
30+
ptbm = tbm([0.8, 1.2]) # a model with 0.8 hopping amplitude to right, 1.2 to the left
3431
3532
using GLMakie
36-
plot(kpi, Es_re, Es_im; color=[:blue, :red])
37-
```
33+
update_theme!(linewidth = 4)
3834
39-
We can also explore the consequences of breaking time-reversal symmetry:
35+
ks = range(-1/2, 1/2, 500) # 500 sampling points
36+
Es = spectrum(ptbm, ks) # 500×1 matrix
37+
Es = vec(Es) # convert to vector
38+
lines(real(Es), imag(Es); axis = (; autolimitaspect = 1))
4039
```
40+
41+
The loop is associated with a quantized spectral winding $\nu = (2\pi \mathrm{i})^{-1}\oint \mathrm{d}k\, \partial_k \log E(k) = \pm 1$ when the two hopping amplitudes are unequal.
42+
43+
44+
### Breaking time-reversal symmetry
45+
46+
We can also create models that do not assume time-reversal symmetry, which here introduces additional imaginary-prefactor counterparts to the standard Hatano--Nelson model:
47+
48+
```@example hatano-nelson
4149
brs_notr = calc_bandreps(1, 1; timereversal=false) # EBRs in plane group 1, without time-reversal symmetry
4250
pin_free!(brs_notr, [1=>[0]])
4351
tbm_notr = tb_hamiltonian((@composite brs_notr[1]), [[0], [1]], NONHERMITIAN) # on-site terms _and_ nearest-neighbor hoppings
4452
```
4553

46-
## A more complicated example: exceptional surfaces in p4
4754

48-
We can also construct more complicated examples where symmetry plays a role. Consider for example the following simple extension of the Hatano-Nelson model to a 2D lattice with p4 symmetry:
49-
```@example hatano-nelson-p4
50-
using Crystalline, SymmetricTightBinding, GLMakie # hide
55+
## Two-band Hatano--Nelson-like model with exceptional points
56+
57+
We can generalize the single-band Hatano--Nelson model from above simply by constructing a two-band model, with two orbitals placed at the unit cell center.
58+
To do so, we simply include two copies of the same EBR in the composite band representation provided to `tb_hamiltonian`: each copy is treated as a separate physical orbital.
59+
60+
```@example hatano-nelson
61+
cbr = @composite 2brs[1]
62+
tbm = tb_hamiltonian(cbr, [[0], [1]], Val(NONHERMITIAN))
63+
summary(tbm)
64+
```
65+
66+
The resulting model has 10 free terms: the first 6 are self-couplings (self-energies and intercell hoppings between the same physical orbital); the last 4 are hoppings between the two distinct orbitals. We restrict the model to this subset in the interest of simplicity:
67+
68+
```@example hatano-nelson
69+
tbm = tbm[7:10]
70+
```
71+
72+
The four terms span a model of the kind:
73+
74+
```math
75+
\mathbf{H}(k) =
76+
\begin{bmatrix}
77+
0 & t_1 + t_2 \mathrm{e}^{2\pi\mathrm{i}k} \\
78+
t_1' + t_2' \mathrm{e}^{-2\pi\mathrm{i}k} & 0
79+
\end{bmatrix},
80+
```
81+
82+
with intercell hoppings $t_2^{(\prime)}$ and intracell hoppings $t_1^{(\prime)}$.
83+
A specific instance of this model can be created from `tbm` via `tbm([t₁, t₂, t₁′, t₂′])`.
84+
85+
An simple special case -- but interesting, as we will see -- is equal inter- and intracell hoppings from orbital 2 to orbital 1 ($2\rightarrow 1$ hopping), i.e., $t_1 = t_2 = 1$, fully suppressed intercell $1 \rightarrow 2$ hopping, i.e., $t_2' = 0$ and free intracell $1 \rightarrow 2$ hopping, i.e., $t_1' = t$.
86+
With this restriction, the model features an exceptional point (band degeneracy without a complete associated eigenfunction basis), occuring when $t_1 + t_2 \mathrm{e}^{2\pi\mathrm{i}k} = 1 + \mathrm{e}^{2\pi\mathrm{i}k} = 0$, i.e., when $\mathrm{e}^{2\pi\mathrm{i}k} = -1 \Leftrightarrow k = \pm 1/2$ (the BZ edge).
87+
At the exceptional point, the Bloch Hamiltonian is defective in the sense that it is similar to a Jordan block $\big[\begin{smallmatrix} 0 & 1 \\ 0 & 0\end{smallmatrix}\big]$:
88+
89+
```@example hatano-nelson
90+
t = .5 # intracell 1→2 hopping amplitude t₁′
91+
t₁, t₂, t₁′, t₂′ = 1, 1, t, 0
92+
ptbm = tbm([t₁, t₂, t₁′, t₂′])
93+
ptbm([1/2]) # evaluate the Bloch Hamiltonian at k = 1/2
94+
```
95+
96+
We can visualize the resulting spectrum of the model over the Brillouin zone to learn more:
97+
98+
```@example hatano-nelson
99+
ks = range(-1/2, 1/2, 500)
100+
Es = spectrum(ptbm, ks)
101+
Es_re = real(Es) # real parts
102+
Es_im = imag(Es) # imaginary parts
103+
104+
faxp = lines(ks, Es_re[:,1]; color=:royalblue, label = "Re " * rich("E", font=:italic) * subscript("1"))
105+
lines!(ks, Es_im[:,1]; color=:royalblue, label = "Im " * rich("E", font=:italic) * subscript("1"), linestyle=:dash)
106+
lines!(ks, Es_re[:,2]; color=:firebrick2, label = "Re " * rich("E", font=:italic) * subscript("2"))
107+
lines!(ks, Es_im[:,2]; color=:firebrick2, label = "Im " * rich("E", font=:italic) * subscript("2"), linestyle=:dash)
108+
faxp.axis.xlabel = "Momentum " * rich("k", font=:italic)
109+
faxp.axis.ylabel = "Energy " * rich("E", font=:italic)
110+
axislegend(faxp.axis; framevisible=false)
111+
xlims!(-1/2, 1/2)
112+
faxp # hide
113+
```
114+
115+
The spectrum is degenerate at $k = \pm 1/2$ as expected, generally complex, and exhibiting both time-reversal symmetry $E_1(k) = E_2(-k)^*$ and ``accidental'' particle-hole symmetry $E_1(k) = -E_1(k)$ (resulting from our restriction to a small set of hopping hoppings terms).
116+
117+
118+
### Exceptional points with PT symmetry
119+
120+
Exceptional points are especially interesting in contexts where the Hamiltonian is not only non-Hermitian but also PT-symmetric (inversion and time).
121+
The previous Hatano--Nelson-like model, however, is T-symmetric (by default, `calc_bandreps` assumes time-reversal symmetry, and this assumption is propagated via `brs` and `cbr` to `tb_hamiltonian`) but inversion-broken, and so lacks PT-symmetry.
122+
123+
We can build a variant, however, that breaks both P and T but retains PT symmetry.
124+
To do so, first construct the terms of a time-reversal model, starting now with a set of time-reversal broken EBRs:
125+
126+
```@example PT-symmetry
127+
using Crystalline, SymmetricTightBinding # hide
128+
brs = calc_bandreps(1, 1; timereversal=false) # a single EBR, as before, but now without assumption of time-reversal
129+
pin_free!(brs, [1=>[0]]) # as before, pin free parameters of the EBR's Wyckoff position
130+
cbr = @composite 2brs[1]
131+
tbm = tb_hamiltonian(cbr, [[0], [1]], Val(NONHERMITIAN))
132+
summary(tbm)
133+
```
134+
135+
The resulting model has no less than 20 possible terms: simply due to being a fully unconstrained problem -- lack both hermitian, spatial, and time-reversal symmetry.
136+
We pick a small subset of these terms, with the aim of building a simple model. In particular, we retain imaginary onsite terms and the terms in our previous reduced model:
137+
138+
```@example PT-symmetry
139+
onsite_terms = [2, 8]
140+
hopping_terms = [13, 15, 17, 19]
141+
tbm = tbm[vcat(onsite_terms, hopping_terms)]
142+
```
143+
144+
The span of these terms result in a Bloch Hamiltonian:
145+
146+
```math
147+
\mathbf{H}(k) =
148+
\begin{bmatrix}
149+
\mathrm{i}\gamma_1 & t_1 + t_2 \mathrm{e}^{2\pi\mathrm{i}k} \\
150+
t_1' + t_2' \mathrm{e}^{-2\pi\mathrm{i}k} & \mathrm{i}\gamma_2
151+
\end{bmatrix}.
152+
```
153+
154+
Choosing $\gamma_1 = -\gamma_2 = \gamma$, $t_1 = t_1'$, and $t_2 = t_2'$ we obtain a PT symmetric model:
155+
156+
```math
157+
\mathbf{H}(k) =
158+
\begin{bmatrix}
159+
\mathrm{i}\gamma & t_1 + t_2 \mathrm{e}^{2\pi\mathrm{i}k} \\
160+
t_1 + t_2 \mathrm{e}^{-2\pi\mathrm{i}k} & -\mathrm{i}\gamma
161+
\end{bmatrix}.
162+
```
163+
164+
The spectrum of the model is $E_\pm(k) = \sqrt{|t_1+t_2\mathrm{e}^{2\pi\mathrm{i}k}|^2 - \gamma^2}$, which is degenerate -- in fact, exceptional -- when $|t_1+t_2\mathrm{e}^{2\pi\mathrm{i}k}| = \gamma$ (assuming $\gamma>0$). The spectrum is qualitatively distinct before and after the exceptional point:
165+
- When $|t_1+t_2\mathrm{e}^{2\pi\mathrm{i}k}| > \gamma$: $E_\pm(k)$ is real (PT-unbroken phase).
166+
- When $|t_1+t_2\mathrm{e}^{2\pi\mathrm{i}k}| < \gamma$: $E_\pm(k)$ is imaginary (spontaneously broken PT-symmetry).
167+
168+
We can see this readily by constructing the associated Hamiltonian from `tbm`, noting that `tbm([γ₁, γ₂, t₁, t₂, t₁′, t₂′])` corresponds to the general model and `tbm([γ, -γ, t₁, t₂, t₁, t₂])` to the PT-symmetric one:
169+
170+
```@example PT-symmetry
171+
γ, t₁, t₂ = 0.5, 1, 1
172+
ptbm = tbm([γ, -γ, t₁, t₂, t₁, t₂])
173+
174+
# calculate spectrum
175+
ks = range(-1/2, 1/2, 500)
176+
Es = spectrum(ptbm, ks)
177+
Es_re = real(Es) # real parts
178+
Es_im = imag(Es) # imaginary parts
179+
Es_re = sort(Es_re; dims=2) # necessary to explicitly sort for visualization, due to intrinsic
180+
Es_im = sort(Es_im; dims=2) # difficult of sorting floating-point rounded complex numbers
181+
182+
# plot spectrum
183+
using GLMakie # hide
184+
update_theme!(linewidth = 4) # hide
185+
f = Figure()
186+
ax = Axis(f[1,1])
187+
lines!(ks, Es_re[:,1]; color=:royalblue, label="Re " * rich("E", font=:italic) * subscript("−"))
188+
lines!(ks, Es_im[:,1]; color=:royalblue, label="Im " * rich("E", font=:italic) * subscript("−"), linestyle=:dash)
189+
lines!(ks, Es_re[:,2]; color=:firebrick2, label="Re " * rich("E", font=:italic) * subscript("+"))
190+
lines!(ks, Es_im[:,2]; color=:firebrick2, label="Im " * rich("E", font=:italic) * subscript("+"), linestyle=:dash)
191+
ax.xlabel = "Momentum " * rich("k", font=:italic)
192+
ax.ylabel = "Energy " * rich("E", font=:italic)
193+
axislegend(ax; framevisible=false)
194+
xlims!(-1/2, 1/2)
195+
f # hide
196+
```
197+
198+
## 2-band non-Hermitian SSH model
199+
***WIP***
200+
201+
```@example nonhermitian-ssh
202+
using Crystalline, SymmetricTightBinding # hide
203+
# (1b|A′) ⊕ (1a|A′) in 1D SG 2 (inversion symmetry); with intra-cell hoppings & onsite terms
204+
brs = calc_bandreps(2, Val(1))
205+
cbr = @composite brs[1] + brs[3]
206+
tbm = tb_hamiltonian(cbr, [[0], [2]], Val(NONHERMITIAN))
207+
208+
# retain only inter-orbital (offdiagonal) terms for simplicity
209+
tbm = tbm[5:8]
210+
ptbm = tbm([.5, 1, 1, .5]) # antisymmetric hopping pattern
211+
212+
# calculate spectrum
213+
ks = range(-1/2, 1/2, 500)
214+
Es = spectrum(ptbm, ks)
215+
Es_re = real(Es) # real parts
216+
Es_im = imag(Es) # imaginary parts
217+
Es_re = sort(Es_re; dims=2) # necessary to explicitly sort for visualization, due to intrinsic
218+
Es_im = sort(Es_im; dims=2) # difficult of sorting floating-point rounded complex numbers
219+
220+
# plot spectrum
221+
using GLMakie # hide
222+
update_theme!(linewidth = 4) # hide
223+
f = Figure()
224+
ax = Axis(f[1,1])
225+
lines!(ks, Es_re[:,1]; color=:royalblue, label="Re " * rich("E", font=:italic) * subscript("−"))
226+
lines!(ks, Es_im[:,1]; color=:royalblue, label="Im " * rich("E", font=:italic) * subscript("−"), linestyle=:dash)
227+
lines!(ks, Es_re[:,2]; color=:firebrick2, label="Re " * rich("E", font=:italic) * subscript("+"))
228+
lines!(ks, Es_im[:,2]; color=:firebrick2, label="Im " * rich("E", font=:italic) * subscript("+"), linestyle=:dash)
229+
ax.xlabel = "Momentum " * rich("k", font=:italic)
230+
ax.ylabel = "Energy " * rich("E", font=:italic)
231+
axislegend(ax; framevisible=false)
232+
xlims!(-1/2, 1/2)
233+
f # hide
234+
```
235+
236+
## A more complicated example: exceptional lines in p4
237+
238+
We can also construct more complicated examples where symmetry plays a role.
239+
Consider for example a non-Hermitian model on a 2D lattice with p4 symmetry, obtained by placing *s*-like orbitals at the two symmetry-related edges of the unit cell (i.e., a (2c|A) orbital):
240+
241+
```@example nonhermitian-p4
242+
using Crystalline, SymmetricTightBinding # hide
51243
brs = calc_bandreps(10, Val(2))
52-
cbr = @composite brs[1]
244+
cbr = @composite brs[1] # pick the (2c|A) EBR
53245
tbm_H = tb_hamiltonian(cbr, [[0,0], [1,0]], Val(HERMITIAN))
54246
tbm_NH = tb_hamiltonian(cbr, [[0,0], [1,0]], Val(NONHERMITIAN))
55247
```
56248

57249
It is instructive to visualize both the Hermitian and non-Hermitian models and compare the involved hopping terms:
58250

59-
```@example hatano-nelson-p4
251+
```@example nonhermitian-p4
252+
using GLMakie # hide
253+
update_theme!(linewidth = 4) # hide
60254
plot(tbm_H)
255+
```
256+
257+
```@example nonhermitian-p4
61258
plot(tbm_NH)
62259
```
260+
261+
The second and third terms of the non-Hermitian model clearly break Hermiticity (unless of equal amplitude).
262+
We can verify that the model hosts exceptional lines in this case:
263+
264+
```@example nonhermitian-p4
265+
tbm = tbm_NH[2:3] # retain only terms 2 and 3
266+
ptbm_NH = tbm([1.2, 0.8]) # 1.2 vs. 0.8 hopping asymmetry
267+
ks = range(-1/2, 1/2, 201)
268+
Em = [spectrum_single_k(ptbm_NH, [k1, k2]) for k1 in ks, k2 in ks]
269+
270+
# sort the real and imaginary parts of the energies for plotting purposes
271+
Em_re = [sort(real(_Es)) for _Es in Em]
272+
Em_im = [sort(imag(_Es)) for _Es in Em]
273+
Es_re_1 = getindex.(Em_re, 1) # band 1
274+
Es_im_1 = getindex.(Em_im, 1)
275+
Es_re_2 = getindex.(Em_re, 2) # band 2
276+
Es_im_2 = getindex.(Em_im, 2)
277+
278+
# plotting configurations
279+
E_label = rich("E", font=:italic) * subscript("±")
280+
axis_args = (;
281+
aspect = (1,1,.75),
282+
xautolimitmargin = (0,0), yautolimitmargin = (0,0),
283+
xlabel = rich("k"; font=:italic) * subscript("1"), xlabeloffset = 10,
284+
ylabel = rich("k"; font=:italic) * subscript("2"), ylabeloffset = 10,
285+
zlabeloffset = 35,
286+
xticks = [-1/2, 0, 1/2], xticklabelsvisible = false,
287+
yticks = [-1/2, 0, 1/2], yticklabelsvisible = false
288+
)
289+
colorbar_args = (; vertical = false, height = 8, ticklabelsize = 12)
290+
shininess = 1.0
291+
lims_re = extrema(Iterators.flatten(Em_re))
292+
lims_im = extrema(Iterators.flatten(Em_im))
293+
294+
# plot the real and imaginary energy surfaces across the BZ
295+
f = Figure(size=(600,280), figure_padding=(20,0,0,5))
296+
rowgap!(f.layout, 0)
297+
298+
ax1 = Axis3(f[2,1]; zlabel="Re "*E_label, axis_args...)
299+
p1 = surface!(ks, ks, Es_re_1; colormap=:PiYG_8, colorrange=lims_re, shininess)
300+
surface!( ks, ks, Es_re_2; colormap=:PiYG_8, colorrange=lims_re, shininess)
301+
zlims!(ax1, lims_re)
302+
Colorbar(f[1,1], p1; ticks=([.9999*lims_re[1], 0, .9999*lims_re[2]], ["min", "0", "max"]), colorbar_args...)
303+
304+
ax2 = Axis3(f[2,2]; zlabel="Im "*E_label, axis_args...)
305+
p2 = surface!(ks, ks, Es_im_1; colormap=:RdBu_8, colorrange=lims_im, shininess)
306+
surface!( ks, ks, Es_im_2; colormap=:RdBu_8, colorrange=lims_im, shininess)
307+
zlims!(ax2, lims_re)
308+
Colorbar(f[1,2], p2; ticks=([.9999*lims_im[1], 0, .9999*lims_im[2]], ["min", "0", "max"]), colorbar_args...)
309+
f # hide
310+
```

0 commit comments

Comments
 (0)