Skip to content

Commit 2c0990d

Browse files
authored
Generalize implementation to treat non-Hermitian models (#106)
* Generalize to non-Hermitian models * fix copilot finds & add docstring for `TightBindingTerm` - also a fix for an error in the docs CI (add a docstring for `TightBindingTerm`) * fix missing code loading in docs examples * split `spectrum` into two functions: `spectrum` and `spectrum_single_k` for multiple/single **k**-points - `spectrum_single_k` now handles case where a *single* **k**-point is provided and `spectrum` is strictly for *multiple* of **k**-points - by splitting up like this, we also enable the introduction of convenience method for 1D models, using `spectrum(..., ks)` with a plain (abstract) vector of real numbers; this is just much nicer in day-to-day use. * move `Hermitian` wrapper to instantiation, not at callers * update nonhermitian docs * Make model visualization work for `D=1` as well - mainly, this is a matter of lifting 1D properties (points and unit cell boundaries) to 2D points - while there, we also fix a few old bugs (e.g., the fact that `context.limits` was not properly propagated, which made visualization of model terms with different extents display in a way where their overall extent was not comparable) - co-developed with Claude * add 1D visualization examples to non-Hermitian docs - also fix some writing that referenced terms hopping the opposite way relative to what they actually did - extend non-Hermitian SSH example a bit * ensure that NONHERMITIAN models return terms that are "hermiticity-paired" - This ensures that every term in a nonhermitian TB model has a counterpart that it would be mapped to under Hermitian conjugation. This is just much more natural and aligned with what a user would expect. The issue only arose for diagonal blocks of a Hamiltonian, with the canonical case being e.g., a (2c|A) EBR model in p4. - This also fixes a related issue, arguably a bug, in the (ANTI)HERMITIAN case, where some orbits weren't sufficiently "wide" (not enough hopping terms) to close under (anti-)Hermiticity, unless `Rs` was provided in such a way that for every positive element `R` there was also a negative element `-R`. We fix this by explicitly checking in `add_reversed_hoppings!` whether for every a→b+R term of separation δ, there is a corresponding b→a-R term at separation -δ. * fix to `spectrum`; wrongly had `transform` as arg instead of kwarg. * polish docs/src/nonhermitian.md and flesh out non-Hermitian SSH example * improve consistency of arrow-shortening in model visualization
2 parents c4dbaa5 + 3957fa1 commit 2c0990d

23 files changed

Lines changed: 1100 additions & 304 deletions

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ hopping ranges, the package:
2222
## Key types and API
2323

2424
### Core pipeline
25-
- `tb_hamiltonian(cbr, Rs; antihermitian)` — top-level entry point; returns `TightBindingModel`
25+
- `tb_hamiltonian(cbr, Rs, ::Val{<:Hermiticity})` — top-level entry point; returns `TightBindingModel`
2626
- `obtain_symmetry_related_hoppings(Rs, br_a, br_b)` — enumerates hopping orbits
2727
- `sgrep_induced_by_siteir(br, op)` — site-symmetry induced space group representation
2828

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ makedocs(;
2525
"Band symmetry" => "band-symmetry.md",
2626
"Berry curvature & Chern numbers" => "berry.md",
2727
"Symmetry breaking" => "symmetry-breaking.md",
28+
"Non-Hermitian models" => "nonhermitian.md",
2829
"API" => "api.md",
2930
"Internal API" => "internal-api.md",
3031
"Theory" => "theory.md",

docs/src/band-symmetry.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ To explore these tools, we first re-build the graphene model previously explored
1111
sgnum = 17 # plane group p6mm
1212
brs = calc_bandreps(sgnum, Val(2)) # band representations
1313
cbr = @composite brs[5] # (2b|A₁) EBR
14-
tbm = tb_hamiltonian(cbr) # tight-binding model (nearest neigbors)
14+
tbm = tb_hamiltonian(cbr) # tight-binding model (nearest neighbors)
1515
ptbm = tbm([0, 1]) # zero self-energy, nonzero nearest-neighbor hopping
1616
Rs = directbasis(sgnum, Val(2)) # (conventional) direct lattice basis
1717
kp = irrfbz_path(sgnum, Rs) # high-symmetry k-path
@@ -78,6 +78,8 @@ calc_topology.(ns, Ref(brs))
7878

7979
I.e., in this example, both band representations are either a trivial or a fragile phase. To resolve this distinction, we can use [SymmetryBases.jl](https://github.com/thchr/SymmetryBases.jl)'s `calc_detailed_topology`:
8080
```@repl band-symmetry
81+
redirect_stdout(devnull) do # hide
8182
using SymmetryBases
83+
end # hide
8284
calc_detailed_topology.(ns, Ref(brs))
8385
```

docs/src/nonhermitian.md

Lines changed: 361 additions & 0 deletions
Large diffs are not rendered by default.

docs/src/symmetry-breaking.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ We start by constructing our symmetry-unbroken model, picking the (2c|A₁) band
1010
using Crystalline, SymmetricTightBinding
1111
brs = calc_bandreps(11, Val(2))
1212
cbr = @composite brs[1]
13-
tbm = tb_hamiltonian(cbr, [[0,0], [1,0]])
13+
tbm = tb_hamiltonian(cbr, [[0,0], [1,0]])[1:4] # restrict to 4 simplest terms
1414
ptbm = tbm([0, 1, -1, 1])
1515
```
1616

@@ -47,7 +47,7 @@ This allows three additional terms. Conversely, we could have also tried to brea
4747
Δtbm_tr = subduced_complement(tbm, 11; timereversal = false) # break TR
4848
```
4949

50-
[^1]: For mirror symmetry-breaking, the absence of new terms is a result of looking only at a limited set of hopping orbits (in the original model `tb_hamiltonian(cbr, [[0,0], [1,0]])`): by including longer-range hopping orbits, we would eventually find new mirror-symmetry-broken terms. This is not so for time-reversal breaking, however: in *p*4mm, mirror symmetry and hermicity jointly impose an effective time-reversal symmetry.
50+
[^1]: For mirror symmetry-breaking, the absence of new terms is a result of looking only at a limited set of hopping orbits (in the original model `tb_hamiltonian(cbr, [[0,0], [1,0]])`): by including longer-range hopping orbits, we would eventually find new mirror-symmetry-broken terms. This is not so for time-reversal breaking, however: in *p*4mm, mirror symmetry and hermiticity jointly impose an effective time-reversal symmetry.
5151

5252
However, by breaking both mirror and time-reversal symmetry simultaneously, additional terms do appear:
5353

examples/sg213.jl

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)