Conventions
Units
Unless explicitly stated otherwise:
lattice vectors are in angstrom,
reciprocal vectors are in angstrom^-1,
fractional coordinates are expressed with respect to lattice vectors.
Variables
The following naming conventions are used consistently across code and docs.
Names
U: unitary transformation matricesA: initial projection matrix (amnin Wannier90 terminology)
M: overlap matrices between neighboring kpoints, i.e.,mmnof Wannier90
Dimensions
Dimension variables are prefixed with n_.
n_bands: number of bandsn_wann: number of WFsn_kpts: number of kpointsn_bvecs: number of b-vectorsn_atoms: number of atoms
Indices
Usually, the returned quantities are Vectors of some types (Matrix{Float64}, Vector{Float64}, etc), and the indices follow the order of
kpoints
b-vectors (if needed)
bands
Wannier functions
For instance, the energy eigenvalues eigenvalues is a length-n_kpts vector, with each element a length-n_bands vector of floats, i.e., eigenvalues[ik][ib] is the ib-th eigenvalue at ik-th kpoint.
Here are some examples of indexing the vectors:
eigenvalues[ik][m]for energy eigenvaluesU[ik][m, n]for the gauge matrixM[ik][ib][m, n]for the overlap matrix
where
ik: index of kpointsib: index of b-vectorsm: index of bandsn: index of Wannier functions
Containers
Reader/writer APIs follow a simple rule for returned/accepted grouped data:
If a parser returns up to 3 values, it returns a
NamedTupleIf a parser returns more than 3 values, it returns a thin container
struct
The same thin container structs are accepted by corresponding writer functions. This keeps small APIs lightweight while giving large file formats a centralized data model that downstream packages can reuse.
Functions
Most top-level APIs have multiple dispatch variants. For example, there are format-specific methods for reading chk files:
read_chk(filename::AbstractString)
read_chk(filename::AbstractString, ::FortranText)
read_chk(filename::AbstractString, ::FortranBinary)Why this design:
high-level functions are convenient and automatically detect formats,
low-level methods remain available when explicit format control is needed.
Thus,
In most cases, use the high-level function:
juliajulia> using WannierIO julia> amn = read_amn("si2.amn"); julia> amn.header "Created on 9Sep2022 at 16:41: 5" julia> amn.A 8-element Vector{Matrix{ComplexF64}}: [...]Use low-level methods when you need explicit format control.
juliajulia> using WannierIO julia> amn = read_amn("si2.amn", WannierIO.FortranText()) julia> amn.header "Created on 9Sep2022 at 16:41: 5"
When writing files, high-level methods commonly expose a binary keyword:
julia> write_amn("si2.amn", A; binary=true)This avoids the need to call format-specific low-level methods in typical use.