WTP.OnGrid β€” Type

The orbitals are defined somewhat abstractly as functions on grids. The grid points are often times either real space points or wave numbers, but more generally they are sets of parameters of the a family of functions.

Centering Convention:

An OnGrid complies to the centering convention if it is defined on a grid centered at the origin. This means the domain is from -N to N-1 for an even grid, and -N to N for an odd grid.

source

Creating an Orbital

Base.map β€” Method
map(f, grid)

Map a pure function f onto every grid vector on grid. The map is threaded, so an unpure f would probabbly be unsafe.

More likely than not, you would use the do syntax

Example

julia> homecell = make_grid(HomeCell3D, CARTESIAN_BASIS, size_to_domain((4, 4, 4)));

julia> lattice = transform_grid(homecell);

julia> Ο• = map(r->exp(1im * (lattice[1, 0, 0]' * r)), homecell);

julia> Ο•[homecell[:, 0, 0]]
4-element Vector{ComplexF64}:
                  -1.0 - 1.2246467991473532e-16im
 6.123233995736766e-17 - 1.0im
                   1.0 + 0.0im
 6.123233995736766e-17 + 1.0im

This syntax is very simple and expressive, but keep in mind that this involves compiling an anonymous function for each map, which costs as much as the mapping it self.

source

Indexing

Indexing with a single grid vector

Base.getindex β€” Method
getindex(on_grid, grid_vector)

Indexing an OnGrid object with a grid vector gives the element on the corresponding grid point. Can also write on_grid[grid_vector]

Example:

julia> Ο•[homecell[0, 0, 0]]
0.0
source
Base.setindex! β€” Method
setindex!(on_grid, value, grid_vector)

Set an element of an OnGrid object identified by a grid vector. Can also write on_grid[grid_vector] = value.

Example:

julia> Ο•[homecell[0, 0, 0]] = 24;
julia> Ο•[homecell[0, 0, 0]]
24
julia> Ο•[homecell[0, 0, 0]] = 0; # remember to set it back for later examples.
source

Indexing with an array of grid vectors

Base.getindex β€” Method
getindex(on_grid, grid_vector_array)

Indexing an OnGrid object with an array of grid vectors gives an array of elements with the same dimension.

Example:

julia> Ο•[homecell[:, 0, -1:1]]
4Γ—3 Matrix{Float64}:
 0.0  0.0  0.0
 0.0  0.0  0.0
 0.0  0.0  0.0
 0.0  1.0  0.0
source
Base.setindex! β€” Method
setindex!(on_grid, value, grid_vector)

Set an array of elements of an OnGrid object identified by an array of grid vectors with the same dimension. Can also write on_grid[grid_vector] = value.

Example:

julia> Ο•[homecell[:, 0, 0]] = [4, 3, 2, 1];
julia> Ο•[homecell[:, 0, 0]]
24
julia> Ο•[homecell[:, 0, 0]] = [0, 0, 0, 1]; # remember to set it back for later examples.
source

Normalization

LinearAlgebra.norm β€” Method
norm(on_grid)

The square norm of a function on a grid.

Example:

julia> norm(Ο•)
8.0
source
WTP.square_normalize β€” Function
square_normalize(on_grid)

Normalize on_grid to unit square norm.

Example:

julia> Ο•_2 = square_normalize(Ο•);
julia> norm(Ο•_2)
1.0
source
WTP.square_normalize! β€” Function
square_normalize!(on_grid)

Same as square_normalize, but in place.

Example:

julia> square_normalize!(Ο•);
julia> norm(Ο•)
1.0
source

FFT

WTP.fft β€” Method
fft(on_grid)

Fast Fourier Transform of an OnGrid object.

Example:

julia> Ο•Μƒ = fft(Ο•);
julia> Ο•Μƒ[lattice[:, 0, 0]]
4-element Vector{ComplexF64}:
 -3.061616997868383e-17 - 3.061616997868383e-17im
                    0.0 + 3.061616997868383e-17im
  3.061616997868383e-17 - 3.061616997868383e-17im
                    1.0 + 3.061616997868383e-17im

julia> typeof(ψ)
WTP.SimpleFunctionOnGrid{ReciprocalLattice3D}
source
WTP.ifft β€” Method
ifft(orbital)

Inverse Fast Fourier Transform of an OnGrid object. The memory of the argument will be repurposed for its FFT.

Example:

julia> Ο• = ifft(Ο•Μƒ)

julia> Ο•[homecell[:, 0, 0]]
4-element Vector{ComplexF64}:
                -0.125 - 1.5308084989341915e-17im
 7.654042494670958e-18 - 0.125im
                 0.125 + 0.0im
 7.654042494670958e-18 + 0.125im
julia> typeof(Ο•)
WTP.SimpleFunctionOnGrid{HomeCell3D}
source
WTP.@fft! β€” Macro
@fft!(real_orbital)

Perform a in-place Fourier Transform. real_orbital will be set to nothing.

source
WTP.@ifft! β€” Macro
@ifft!(reciprocal_orbital)

Perform a in-place inverse Fourier Transform. reciprocal_orbital will be set to nothing.

source

Arithmatics

WTP.mul β€” Method
mul(o_1, o_2)

Elementwise product. Can also write o_1 * o_2 when both of them are bra or ket.

source
Base.abs2 β€” Method
abs2(o_1)

Elementwise abs2. Handy for computing the density.

Example:

julia> sum(elements(abs2(Ο•)))
1.0
source
WTP.braket β€” Method
braket(o_1, o_2)

⟨o1 | o2⟩. It does not matter whether o_1 or o_2 is a ket. braket will do the right thing. Can also write o_1' * o_2, where o_1' has to be a bra and o_2 must be a ket.

Example:

julia> braket(Ο•, Ο•)
1.0 + 0.0im
julia> ψ' * ψ
1.0 + 6.123233995736766e-17im
source

Density center

WTP.compute_r2 β€” Function
r2(homecell)

Compute $r^2$ on a homecell together with its Fourier transform.

Example:

julia> r2, r̃2 = compute_r2(homecell);
julia> r2[homecell[2, 0, 0]]
4.0
julia> r̃2[grid(r̃2)[0, 0, 0]]
288.0 + 0.0im
source
WTP.center_spread β€” Function
center_spread(õ, r̃2)

Compute the center and the spread. Here, õ should generally be fft of the density (instead of the orbital).

The algorithm can fail when the center is ill-defined

Example:

julia> center_spread(fft(abs2(ϕ), false), r̃2)
([NaN, NaN, NaN], NaN)
julia> center_spread(fft(abs2(square_normalize(map(r->r==homecell[0, 0, 0], homecell)))), r̃2)
([0.0, -0.0, -0.0], 8.326672684688674e-17)
source

Misc

WTP.expand β€” Method
expand(on_grid, factors)

Expand (copy) an OnGrid object by factors along the respective directions.

Example:

julia> Ο•Μ‚ = expand(Ο•);

julia> grid(Ο•Μ‚)
type: ReciprocalLattice3D
domain: ((-4, 3), (-4, 3), (-4, 3))
basis:
    ket: 1.571, 0.000, 0.000
    ket: 0.000, 1.571, 0.000
    ket: 0.000, 0.000, 1.571

julia> grid(Ο•)
type: ReciprocalLattice3D
domain: ((-2, 1), (-2, 1), (-2, 1))
basis:
    ket: 1.571, 0.000, 0.000
    ket: 0.000, 1.571, 0.000
    ket: 0.000, 0.000, 1.571
source
WTP.sparsify β€” Function
sparsify(on_grid, threshold=1e-16)

Store the elements of on_grid as a sparse array.

PS: Quantum Espresso seems to have reinvented sparse arrays in trying to store their orbitals (with a spherical energy cutoff) efficeintly.

Example:

julia> Ο•Μƒ_2 = sparsify(Ο•Μƒ, threshold=1e-16);
julia> vectorize(Ο•Μƒ_2)
64-element SparseVector{Number, Int64} with 1 stored entry:
  [2 ]  =  1.0+3.06162e-17im
source
Base.:>> β€” Method
on_grid >> grid_vector

Translate on_grid by grid_vector.

Example:

julia> Ο•Μƒ = Ο•Μƒ >> lattice[1, 0, 0];
julia> Ο•Μƒ[lattice[:, 0, 0]] 
4-element Vector{ComplexF64}:
                    1.0 + 3.061616997868383e-17im
 -3.061616997868383e-17 - 3.061616997868383e-17im
                    0.0 + 3.061616997868383e-17im
  3.061616997868383e-17 - 3.061616997868383e-17im
julia> Ο•Μƒ[lattice[:, 0, 0]]
4-element Vector{ComplexF64}:
-3.061616997868383e-17 - 3.061616997868383e-17im
                    0.0 + 3.061616997868383e-17im
3.061616997868383e-17 - 3.061616997868383e-17im
                    1.0 + 3.061616997868383e-17im
source