Orbital set

WTP.OrbitalSet β€” Type

OrbitalSet is the set of $u_{n, \mathbf{k}}$ orbitals (UnkBasisOrbital) together with a gauge. Organizing the $u_{n, \mathbf{k}}$ orbitals is very easy with this data structure.

source

Create an orbital set

WTP.init_orbital_set β€” Method
init_orbital_set(brillouin_zone, ::Type{T})

Create an empty orbital set where the k-points are in the brillouin_zone and the orbitals are of type T. The default type is UnkBasisOrbital{ReciprocalLattice3D} is you omit the type.

Example:

julia> u = init_orbital_set(brillouin_zone);

julia> typeof(u)
OrbitalSet{UnkBasisOrbital{ReciprocalLattice3D}}

If you are reading orbitals from Quantum Espresso, you should do the following instead.

path_to_si = "../test/test_data/test_5"
wave_functions_list = wave_functions_from_directory(joinpath(path_to_si, "si.save"))
k_map, brillouin_zone = i_kpoint_map(wave_functions_list)
ũ = orbital_set_from_save(wave_functions_list)
ũ[brillouin_zone[0, 0, 0]][1]

# output

ket
grid:
    type: ReciprocalLattice3D
    domain: ((-12, 11), (-12, 11), (-12, 11))
    basis:
        ket: -0.612, -0.612, 0.612
        ket: 0.612, 0.612, 0.612
        ket: -0.612, 0.612, -0.612
kpoint:
    GridVector{BrillouinZone3D}:
        coefficients: [0, 0, 0]
    
band:
    1
source

Basic Usage

Gauge

WTP.Gauge β€” Type

The gauge $U^{k}$ is a set of matrices, where each matrix corresponds to each k-point. The gauge is an instance of OnGrid.

By convention (from MLWF), each column of the gauge corresponds to the coefficients of a transformed $\tilde{u}_{n, k}$ orbital.

row: bands col: wanniers

$| \tilde{u}_{n, k} \rangle = \sum_{m} | u_{m, k} \rangle U^{k}_{m, n}$

source
WTP.Gauge β€” Method
Gauge(brillouin_zone, n)

Create an identity gauge with $n \times n$ matrices as the gauge.

Example:

julia> brillouin_zone = make_grid(BrillouinZone3D, CARTESIAN_BASIS, size_to_domain((4, 4, 4)));

julia> U = Gauge(brillouin_zone, 4)

julia> U[brillouin_zone[0, 0, 1]]
4Γ—4 Matrix{ComplexF64}:
 1.0+0.0im  0.0+0.0im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  1.0+0.0im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.0im  1.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.0im  0.0+0.0im  1.0+0.0im
source
WTP.gauge β€” Function
gauge(orbital_set)

Get the gauge of an orbital set.

source
WTP.set_gauge β€” Function
set_gauge(orbital_set, new_gauge)

Create a new orbital set with the gauge replaced by new_gauge.

source
WTP.commit_gauge β€” Function
commit_gauge(u)

This will numerically perform the gauge transform on the orbitals in u. After the orbitals are update, the gauge will be reset to the identity gauge.

source

Dimensions

WTP.orbital_grid β€” Function
orbital_grid(orbital_set)

Get the common grid of the orbitals contained by the orbital_set.

julia> lattice = orbital_grid(ũ)
type: ReciprocalLattice3D
domain: ((-12, 11), (-12, 11), (-12, 11))
basis:
    ket: -0.612, -0.612, 0.612
    ket: 0.612, 0.612, 0.612
    ket: -0.612, 0.612, -0.612
source
Missing docstring.

Missing docstring for supergrid. Check Documenter's build log for details.

WTP.n_band β€” Method
n_band(orbital_set)

Get the number of bands in the set.

julia> n_band(ũ)
4
source

FFT

WTP.fft β€” Method
fft(u)

Perform an fft on every orbital in the set.

source
WTP.ifft β€” Method
fft(ũ)

Perform an inverse fft on every orbital in the set.

Example:

julia> u = ifft(ũ)
julia> orbital_grid(u)
source

In place fft is also available through @ifft and @fft. The argument to these macros will be set to nothing.

Indexing

Single indexing

Base.getindex β€” Method
getindex(u, k)

Indexing a wannier object with a kpoint gives the set of basis orbitals at that kpoint. The gauge is irrelevant for this type of indexing. One can also write u[k].

Example:

julia> typeof(ũ[brillouin_zone[0, 0, 0]])
Vector{UnkBasisOrbital{ReciprocalLattice3D}} (alias for Array{UnkBasisOrbital{ReciprocalLattice3D}, 1})

The kpoint can be out of the first Brillouin zone. In that case, the basis orbital corresponding to that kpoint will be computed by phase shifting its image in the first Brillouin zone.

julia> k_1, k_2 = brillouin_zone[-2, 0, 0], brillouin_zone[2, 0, 0];
julia> has_overflow(k_2)
true
julia> ũ[k_2][1][lattice[1:4, 0, 0]]
4-element Vector{ComplexF64}:
   -0.01524761578943151 - 0.0422291275292075im
  0.0023520566748192902 - 0.005010400928812839im
   0.001762807696221052 - 0.0006365001497096597im
 -0.0001863994930269115 - 8.750521988524712e-5im

 julia> ũ[k_1][1][lattice[1:4, 0, 0]]
 4-element Vector{ComplexF64}:
    -0.6169403121751041 - 0.28961297828233756im
   -0.01524761578943151 - 0.0422291275292075im
  0.0023520566748192902 - 0.005010400928812839im
   0.001762807696221052 - 0.0006365001497096597im
source

Array Indexing

Not yet implemented.

Double indexing

Base.getindex β€” Method
getindex(u, n, k)

This fetches us the $u_{n, \mathbf{k}}$ orbitals with the gauge applied. Can also write u[n, k]. The result will be a linear combination of orbitals.

Example:

amn = AMN(joinpath(path_to_si, "output/pw2wan/si.amn"))
U = Gauge(grid(ũ), amn, k_map)
ũ = set_gauge(ũ, U)
ũ[1, brillouin_zone[0, 0, 0]]

# output

ket
coefficients:    
    Number[-0.4240209935568641 + 0.06876931361986612im, 0.007756005591334594 - 0.28204917169307464im, 0.8377575800925453 + 0.1167214564594588im, 0.06944769261399274 + 0.12482164973224028im]
n_basis:    
    4
source

Callable indexing

WTP.wannier_orbitals β€” Function
wannier_orbitals(ũ)

Construct all the wannier orbitals in the reciprocal space by interleaving the $u_{n, \mathbf{k}}$ orbtials. Can also write ũ(:). Gettting them one at a time is currently not supported due to pathetic performance.

Keep in mind that this is likely the most costy operation in this package even though the implementation is linear time.

Example:

julia> wanniers = ũ(:);
julia> wanniers[1]
ket
grid:
    type: ReciprocalLattice3D
    domain: ((-48, 47), (-48, 47), (-48, 47))
    basis:
        ket: -0.153, -0.153, 0.153
        ket: 0.153, 0.153, 0.153
        ket: -0.153, 0.153, -0.153
kpoint:
    GridVector{BrillouinZone3D}:
        coefficients: [0, 0, 0]
    
band:
    1
source