Lattice Definition

The most basic feature LatticeTools.jl provides is defining a lattice system, which consist of:

  1. a unit cell, defined by the lattice vectors and the basis sites
  2. Bravais lattice

UnitCell represents the first component, while the second component, its cluster shape and periodic boundary condition for finite a finite size lattice, makes use of Hypercube.

UnitCell

The unit cell of a lattice is represented by UnitCell. The lattice vectors, which defines the size and shape of the unit cell, is stored in a matrix as column vectors. The basis of the unit cell is represented as a list of sites, with ther names and locations within the unit cell. The "name" of a site can be of any arbitrary type (except integer in order to avoid confusion with the site "index"). Their locations are stored in fractional coordinates in units of the lattice vectors as objects of type FractCoord.

Creating a UnitCell is straight forward, using makeunitcell and addsite!. The following example defines a two-dimensional square unit cell with two sites, site A at location [0.1, 0], and site B at location [0.0, 0.1].

using LatticeTools
unitcell = makeunitcell([1.0 0.0; 0.0 1.0]; SiteType=String)
addsite!(unitcell, "A", FractCoord([0,0], [0.1, 0.0]))
addsite!(unitcell, "B", FractCoord([0,0], [0.0, 0.1]))
unitcell
UnitCell{String}([1.0 0.0; 0.0 1.0], Tuple{String,FractCoord}[("A", FractCoord([0, 0] + [0.1, 0.0])), ("B", FractCoord([0, 0] + [0.0, 0.1]))], [1.0 0.0; 0.0 1.0], [6.283185307179586 0.0; 0.0 6.283185307179586], Dict("B" => 2,"A" => 1))

Here FractCoord represents location in the fractional coordinates, i.e. in units of the lattice vectors, with whole ($\in \mathbb{Z}^{D}$) and fraction ($\in [0, 1)^D$) parts.

Hypercube

A finite size lattice with periodic boundary condition can be constructed as a quotient set of an infinite lattice, with equivalence relation defined by a "supercell translation". In such a case, the equivalence relation within the basis under translation is identity; only the equivalence relation within the Bravais lattice needs to be worked out. Hypercube provides methods for calculating equivalence relation.

For example, when the super cell is defined by lattice vectors [3, -1] and [1, 3] (in units of the lattice vectors of the original unit cell),

julia> cube = Hypercube([3 1; -1 3])
Hypercube([3 1; -1 3], Rational{Int64}[3//10 -1//10; 1//10 3//10], LatticeTools.var"#wrap#10"{Array{Int64,2},Array{Rational{Int64},2}}([3 1; -1 3], Rational{Int64}[3//10 -1//10; 1//10 3//10]))

julia> cube.wrap([4, 0])
([1, 0], [1, 1])

Here cube.wrap is similar to divrem: [1, 0] is the super cell translation of [4, 0], and [1, 1] is the remaining translation.

Lattice

Now the two can be combined into a Lattice using makelattice.

julia> lattice = makelattice(unitcell, [3 1; -1 3])
Lattice{String}(UnitCell{String}([1.0 0.0; 0.0 1.0], Tuple{String,FractCoord}[("A", FractCoord([0, 0] + [0.1, 0.0])), ("B", FractCoord([0, 0] + [0.0, 0.1]))], [1.0 0.0; 0.0 1.0], [6.283185307179586 0.0; 0.0 6.283185307179586], Dict("B" => 2,"A" => 1)), Hypercube([3 1; -1 3], Rational{Int64}[3//10 -1//10; 1//10 3//10], LatticeTools.var"#wrap#10"{Array{Int64,2},Array{Rational{Int64},2}}([3 1; -1 3], Rational{Int64}[3//10 -1//10; 1//10 3//10])), [[0, 0], [1, 0], [2, 0], [3, 0], [1, 1], [2, 1], [3, 1], [1, 2], [2, 2], [3, 2]], UnitCell{Tuple{String,Array{Int64,1}}}([3.0 1.0; -1.0 3.0], Tuple{Tuple{String,Array{Int64,1}},FractCoord}[(("A", [0, 0]), FractCoord([0, 0] + [0.03, 0.01])), (("B", [0, 0]), FractCoord([-1, 0] + [0.99, 0.03])), (("A", [1, 0]), FractCoord([0, 0] + [0.33, 0.11])), (("B", [1, 0]), FractCoord([0, 0] + [0.29, 0.13])), (("A", [2, 0]), FractCoord([0, 0] + [0.63, 0.21])), (("B", [2, 0]), FractCoord([0, 0] + [0.59, 0.22999999999999998])), (("A", [3, 0]), FractCoord([0, 0] + [0.9299999999999999, 0.31])), (("B", [3, 0]), FractCoord([0, 0] + [0.89, 0.32999999999999996])), (("A", [1, 1]), FractCoord([0, 0] + [0.23, 0.41])), (("B", [1, 1]), FractCoord([0, 0] + [0.19, 0.43])), (("A", [2, 1]), FractCoord([0, 0] + [0.53, 0.51])), (("B", [2, 1]), FractCoord([0, 0] + [0.49, 0.53])), (("A", [3, 1]), FractCoord([0, 0] + [0.83, 0.61])), (("B", [3, 1]), FractCoord([0, 0] + [0.7899999999999999, 0.63])), (("A", [1, 2]), FractCoord([0, 0] + [0.13000000000000003, 0.71])), (("B", [1, 2]), FractCoord([0, 0] + [0.09, 0.73])), (("A", [2, 2]), FractCoord([0, 0] + [0.43, 0.8099999999999999])), (("B", [2, 2]), FractCoord([0, 0] + [0.39, 0.83])), (("A", [3, 2]), FractCoord([0, 0] + [0.73, 0.9099999999999999])), (("B", [3, 2]), FractCoord([0, 0] + [0.69, 0.9299999999999999]))], [0.3 0.09999999999999999; -0.09999999999999999 0.3], [1.8849555921538759 0.6283185307179586; -0.6283185307179586 1.8849555921538759], Dict(("A", [2, 2]) => 17,("A", [1, 2]) => 15,("B", [3, 2]) => 20,("A", [1, 0]) => 3,("A", [3, 0]) => 7,("B", [2, 2]) => 18,("B", [3, 0]) => 8,("A", [2, 1]) => 11,("B", [1, 2]) => 16,("A", [3, 2]) => 19…)))