$U_{n, \mathbf{k}}$ Orbitals
WTP.AbstractUnkOrbital
β TypeAn AbstractUnkOrbital represents the$u_{n, \mathbf{k}}$ orbitals.
Such a function is also a basis vector and a linear combination. This is where the single subtyping system of Julia gives me headaches.
Basis orbitals
A UnkBasisOrbital
inherits OnGrid
with a few additional properties.
WTP.UnkBasisOrbital
β MethodUnkBasisOrbital(grid, elements, kpoint, index_band)
This is the concrete type that numerically stores the orbital as a function on a grid (either the homecell or the reciprocal lattice). It is also associated with a k-point and an index of a band.
More likely than not, one get these from reading the output of quantum espresso.
julia> lattice = make_grid(ReciprocalLattice3D, CARTESIAN_BASIS, size_to_domain((4, 4, 4)));
julia> Ο = map(g->(g==lattice[1, 0, 0]) |> Float64, lattice);
julia> brillouin_zone = make_grid(BrillouinZone3D, CARTESIAN_BASIS, size_to_domain((3, 3, 3)));
julia> Ο = UnkBasisOrbital(lattice, elements(Ο), brillouin_zone[1, 0, -1], 2)
ket
grid:
type: HomeCell3D
domain: ((-2, 1), (-2, 1), (-2, 1))
basis:
ket: 1.000, 0.000, 0.000
ket: 0.000, 1.000, 0.000
ket: 0.000, 0.000, 1.000
kpoint:
GridVector{BrillouinZone3D}:
coefficients: [1, 0, -1]
band:
2
WTP.kpoint
β Methodkpoint(orbital)
Get the kpoint
associated with the orbital
.
julia> kpoint(Ο)
GridVector{BrillouinZone3D}:
coefficients: [1, 0, -1]
WTP.kpoint!
β Methodkpoint!(orbital, new_kpoint)
Set the kpoint associated with orbital
to new_kpoint
.
julia> kpoint!(Ο, brillouin_zone[0, 0, -1])
ket
grid:
type: HomeCell3D
domain: ((-2, 1), (-2, 1), (-2, 1))
basis:
ket: 1.000, 0.000, 0.000
ket: 0.000, 1.000, 0.000
ket: 0.000, 0.000, 1.000
kpoint:
GridVector{BrillouinZone3D}:
coefficients: [0, 0, -1]
band:
2
WTP.index_band
β Methodindex_band(orbital)
Get the index of the band of the orbital
.
julia> index_band(Ο)
2
WTP.dagger
β Methoddagger(orbital)
Complex conjutate an orbital.
julia> dagger(Ο) |> ket
false
WTP.dagger!
β Methoddagger!(orbital)
Complex conjutate an orbital in place.
Linear combination of orbitals.
WTP.UnkOrbital
β TypeGiven a few basis orbitals, we can construct a linear combination of them for a basic set of symbolic manipulation. A linear combination is named UnkOrbital
due to my stupidity.
This also should be a subtype of OnGrid and Basis, but we are crippled by the single subtyping system.
WTP.UnkOrbital
β MethodUnkOrbital(orbital, orthonormal = true)
Construct a linear combination of orbitals from orbital
as a basis vector. Set orthonormal
to true
for an orthogonal basis set.
julia> Οβ = UnkOrbital(map(g->Float64(g==lattice[1, 0, 0]), lattice), true)
ket
coefficients:
Number[1.0]
n_basis:
1
julia> Οβ = UnkOrbital(map(g->Float64(g==lattice[0, 1, 0]), lattice), true);
julia> Οβ = UnkOrbital(map(g->Float64(g==lattice[0, 0, 1]), lattice), true);
WTP.dagger
β Methoddagger(orbital)
Take the complex conjugate recursively through the basis vectors.
julia> dagger(Οβ) |> ket
false
WTP.dagger!
β Methoddagger!(orbital)
Take the complex conjugate recursively through the basis vectors in place.
WTP.index_band
β Methodindex_band(orbital)
Get the index of the band of the orbital.
WTP.orthonormal
β Methodorthonormal(orbital)
Whether the basis set is orthonormal.
Indexing of linear combinations
Not yet implemented.
Semi-symbolic arithmatics (experimental)
WTP.add
β Methodadd(o_1, o_2, [mutual_orthonormal = false])
Can also write o_1 + o_2
, where mutual_orthonormal = false
is assumed.
Add two linear combination of orbitals. The resulting linear combination has a orthogonal basis set if both linear combinations have orthogonal basis sets and they are mutually orthogonal as specified in mutual_orthonormal
.
julia> Ο_sum = Οβ + Οβ
ket
coefficients:
Number[1.0, 1.0]
n_basis:
2
julia> orthonormal(Ο_sum)
false
julia> Ο_sum = add(Οβ, Οβ, true)
ket
coefficients:
Number[1.0, 1.0]
n_basis:
2
julia> orthonormal(Ο_sum)
true
WTP.negate
β Methodnegate(orbital)
Negate the coefficients of the linear combination. Can also write -orbital
.
WTP.mul
β Methodmul(s, orbital)
Scale coefficients of the linear combination. Can also write s * orbital
or orbital * s
.
WTP.braket
β Methodbraket(o_1, o_2)
Recursively compute the inner product. o_1
must be a bra and o_2
must be a ket (this may be relaxed later). Can also write o_1 * o_2
Example:
julia> Ο_sum' * Οβ
1.0
julia> Ο_sum' * Οβ
0.0
Base.zeros
β Methodzeros(UnkOrbital, dims...)
Create an array of empty linear combination. This enables semi-symbolic linear algebra.
julia> [Οβ, Οβ, Οβ]' * [0 0 1;
0 1 0;
1 0 0] * [Οβ, Οβ, Οβ]
1.0