Skip to content

Commit 8a35356

Browse files
committed
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.
1 parent c41dbf1 commit 8a35356

5 files changed

Lines changed: 54 additions & 17 deletions

File tree

src/SymmetricTightBinding.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export pin_free!
4141
include("symmetry_analysis.jl")
4242
export symmetry_eigenvalues
4343
include("spectrum.jl")
44-
export spectrum
44+
export spectrum, spectrum_single_k
4545
include("gradients.jl")
4646
export gradient_wrt_hopping
4747
export TightBindingModelHoppingGradient

src/spectrum.jl

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
"""
2-
spectrum(ptbm::ParameterizedTightBindingModel, ks; transform = identity)
2+
spectrum(ptbm::ParameterizedTightBindingModel{D, S}, ks; transform = identity)
33
44
Evaluate the spectrum, i.e., energies, of the tight-binding model `ptbm` over an iterable
55
of input momenta `ks`.
66
77
Energies are returned as a matrix, with rows running over momenta and columns over distinct
8-
bands.
8+
bands. If `S == HERMITIAN`, the element types (energies) are `Float64`, and otherwise
9+
`ComplexF64`.
10+
11+
## Arguments
12+
- `ptbm`: a [`ParameterizedTightBindingModel`](@ref) to evaluate the spectrum of.
13+
- `ks`: An iterable of momenta. Each such momentum `ks[i]` must evaluate to a real
14+
`D`-dimensional abstract vector. If `D = 1` (1D models), `ks` can also be any abstract
15+
vector of real numbers.
916
1017
## Keyword arguments
1118
@@ -50,19 +57,30 @@ function spectrum(
5057
ResultType = S === HERMITIAN ? Float64 : ComplexF64
5158
Es = Matrix{ResultType}(undef, length(ks), ptbm.tbm.N)
5259
for (i, k) in enumerate(ks)
53-
es = spectrum(ptbm, k; transform)
60+
es = spectrum_single_k(ptbm, k; transform)
5461
@inbounds Es[i, :] .= es
5562
end
5663
return Es
5764
end
5865

66+
# if the model is 1D (D==1), we also provide a convenience method that allows passing a
67+
# any abstract vector of real numbers, each an interpreted as independent momentum point
68+
function spectrum(
69+
ptbm::ParameterizedTightBindingModel{1, S},
70+
ks::AbstractVector{<:Real},
71+
transform::F = nothing
72+
) where {S, F}
73+
ks = [[k] for k in ks]
74+
return spectrum(ptbm, ks; transform)
75+
end
76+
5977
"""
60-
spectrum(ptbm::ParameterizedTightBindingModel, k::AbstractVector{<:Real})
78+
spectrum_single_k(ptbm::ParameterizedTightBindingModel, k::AbstractVector{<:Real})
6179
6280
Evaluate the spectrum, i.e., energies, of the tight-binding model `ptbm` at a single
6381
momentum `k`, across all the bands of `ptbm`.
6482
"""
65-
function spectrum(
83+
function spectrum_single_k(
6684
ptbm::ParameterizedTightBindingModel{D, S},
6785
k::AbstractVector{<:Real};
6886
transform::F = nothing

test/gradients.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ using LinearAlgebra
7474

7575
# verify via finite differences: ∂Eₙ/∂cᵢ ≈ [Eₙ(c+εeᵢ) - Eₙ(c-εeᵢ)] / 2ε
7676
ε = 1e-8
77-
Es_ref = spectrum(ptbm, k)
77+
Es_ref = spectrum_single_k(ptbm, k)
7878
for i in 1:length(cs)
7979
cs₊ = copy(cs); cs₊[i] += ε
8080
cs₋ = copy(cs); cs₋[i] -= ε
81-
Es₊ = spectrum(tbm(cs₊), k)
82-
Es₋ = spectrum(tbm(cs₋), k)
81+
Es₊ = spectrum_single_k(tbm(cs₊), k)
82+
Es₋ = spectrum_single_k(tbm(cs₋), k)
8383
dEs_fd = (Es₊ .- Es₋) ./ (2ε)
8484
dEs_analytic = [∇Es[n][i] for n in 1:tbm.N]
8585
@test dEs_analytic dEs_fd atol=1e-5

test/pg_tb_hamiltonian.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ using LinearAlgebra
6969
# C₄ symmetry: H(k₁,k₂) and H(k₂,-k₁) should have same spectrum
7070
k = [0.1, 0.3]
7171
k_rot = [0.3, -0.1] # C₄ rotation in reciprocal space
72-
es = spectrum(ptbm, k)
73-
es_rot = spectrum(ptbm, k_rot)
72+
es = spectrum_single_k(ptbm, k)
73+
es_rot = spectrum_single_k(ptbm, k_rot)
7474
@test es es_rot atol=1e-10
7575
end
7676

test/spectrum.jl

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ using LinearAlgebra
1313

1414
@testset "Single k-point" begin
1515
k = [0.2, -0.1]
16-
es = spectrum(ptbm, k)
16+
es = spectrum_single_k(ptbm, k)
1717
@test length(es) == 2 # 2 bands
1818
@test issorted(es) # eigenvalues sorted
1919

@@ -30,14 +30,14 @@ using LinearAlgebra
3030

3131
# verify consistency with single-k method
3232
for (i, k) in enumerate(ks)
33-
@test Es[i, :] spectrum(ptbm, k)
33+
@test Es[i, :] spectrum_single_k(ptbm, k)
3434
end
3535
end
3636

3737
@testset "Transform keyword" begin
3838
k = [0.0, 0.0]
39-
es = spectrum(ptbm, k)
40-
es_sq = spectrum(ptbm, k; transform=x->x^2)
39+
es = spectrum_single_k(ptbm, k)
40+
es_sq = spectrum_single_k(ptbm, k; transform=x->x^2)
4141
@test es_sq es.^2
4242

4343
ks = [[0.0, 0.0], [0.5, 0.0]]
@@ -47,11 +47,30 @@ using LinearAlgebra
4747

4848
@testset "Graphene Dirac point" begin
4949
# at K = (1/3, 1/3), graphene should have a degeneracy
50-
es_K = spectrum(ptbm, [1/3, 1/3])
50+
es_K = spectrum_single_k(ptbm, [1/3, 1/3])
5151
@test es_K[1] es_K[2] atol=1e-10
5252

5353
# at Gamma, bands should be split
54-
es_Γ = spectrum(ptbm, [0.0, 0.0])
54+
es_Γ = spectrum_single_k(ptbm, [0.0, 0.0])
5555
@test abs(es_Γ[2] - es_Γ[1]) > 1e-1
5656
end
57+
58+
@testset "D = 1 convenience method" begin
59+
brs_1D = calc_bandreps(2, Val(1))
60+
cbr_1D = @composite brs_1D[1]+brs_1D[3] # 2 bands
61+
tbm_1D = tb_hamiltonian(cbr_1D, [[0], [1]])
62+
ptbm_1D = tbm_1D([0.1, 0.2, -0.3, 0.4, -0.5])
63+
# for 1D models, we allow passing a vector of real numbers, each interpreted as
64+
# independent momentum points
65+
ks_numbers = [0.0, 0.25, 0.5, 0.75] # ::Vector
66+
ks_points = [[k] for k in ks_numbers]
67+
@test spectrum(ptbm_1D, ks_numbers) spectrum(ptbm_1D, ks_points)
68+
69+
ks_numbers_range = range(0, 1/2, 10) # ::StepRange (an `AbstractVector`)
70+
ks_points_range = [[k] for k in ks_numbers_range]
71+
@test spectrum(ptbm_1D, ks_numbers_range) spectrum(ptbm_1D, ks_points_range)
72+
73+
# we should still throw an informative error if we try to do this with a D≠1 model
74+
@test_throws ErrorException spectrum(ptbm, ks_numbers)
75+
end
5776
end

0 commit comments

Comments
 (0)