Lattices

We can use Bloqade to simulate the quantum evolution of information stored in neutral atoms. Present-day neutral-atom hardware permits the arrangement of atoms in a regular lattice structure and even in nearly arbitrary geometries in 1D, 2D, and 3D. This makes neutral atom platform a natural playground for quantum simulation of statistical models and quantum matters. With Bloqade, we support several built-in lattice structures and also allow the users to specify atom positions by inputting coordinates. Please refer to the Rydberg Blockade page for recommendations on how to set the lattice constants for different lattices.

Types of Lattices

A crystal lattice is completely determined by a set of Bravais lattice vectors (in unit of μm) plus the locations of atoms within a unit cell. A Bravais lattice is an infinite array of discrete points generated by a set of discrete translation operations described by

\[\mathbf{R} = n_1 \mathbf{a}_1 + n_2 \mathbf{a}_2 + \ldots + n_d \mathbf{a}_d,\]

where $d$ is the dimension of space, $n_1, \ldots, n_d \in Z$ are integers. The unit cell of a Bravais lattice is defined by specifying its lattice vectors $(\mathbf{a}_1, \mathbf{a}_2, \ldots, \mathbf{a}_d)$. To create a simple lattice, we first specify the locations of the atoms within a unit cell and then specify the lattice vectors of the Bravais lattice. For example, for a triangular lattice, we need just one site (atom) at the location (0.0, 0.0) in the unit cell and then lattice vectors (1.0, 0.0) and (0.5, 0.5*sqrt(3)):

julia> using Bloqade
julia> triangular = GeneralLattice([(1.0, 0.0), (0.5, 0.5*sqrt(3))], [(0.0, 0.0)])GeneralLattice{2, 1, Float64}(((1.0, 0.0), (0.5, 0.8660254037844386)), ((0.0, 0.0),))

For composite lattices, one should provide multiple sites as the second argument to specify their locations in a unit cell. For example, the honeycomb lattice can be defined by:

julia> honeycomb = GeneralLattice([(1.0, 0.0), (0.5, 0.5*sqrt(3))],
           [(0.0, 0.0), (0.5, 0.5/sqrt(3))])GeneralLattice{2, 2, Float64}(((1.0, 0.0), (0.5, 0.8660254037844386)), ((0.0, 0.0), (0.5, 0.2886751345948129)))

We provide a few shorthands for several useful lattices, including the ChainLattice, SquareLattice, HoneycombLattice, TriangularLattice, LiebLattice, and KagomeLattice shown below. One can use lattice_vectors and lattice_sites to access the lattice vectors and site locations in a unit cell as described in the above section.

ChainLattice
using Bloqade
chain = ChainLattice()
ChainLattice()
# to make the plot look good in both light and dark backgrounds.
BloqadeLattices.DEFAULT_BACKGROUND_COLOR[] = "#FFFFFF"

# to show the lattice vectors (rescaled a bit to shrink the head).
unitvectors(lattice::AbstractLattice{2}) = [((0.0, 0.0), v) for v in lattice_vectors(lattice)]

Bloqade.plot(generate_sites(chain, 10); vectors=[((0.0, 0.0), (0.9, 0.0))], bond_linewidth=0.015)
Example block output
Note

You can see the above visualization in one of the following editors

but not in a Julia REPL which does not have a graphical display.

lattice_vectors(chain)
((1.0,),)
lattice_sites(chain)
((0.0,),)

Once we have defined certain lattice shapes (which have fixed lattice vectors and site positions in the unit cell), we can generate the atom positions by specifying the number of atoms and the scale size of the lattice. This is done by using the function generate_sites , which will return a AtomList instance containing the coordinates of each atom, e.g.:

atoms = generate_sites(HoneycombLattice(), 3, 5; scale = 4.5)
Example block output

where scale defines the unit distance in the unit μm of the lattice, and 3, 5 specifies the repetitions of unit cells in each lattice vector direction. The default scale is 1 μm.

Here are some examples of other lattices:

SquareLattice
square = SquareLattice()
Bloqade.plot(generate_sites(square, 10, 10); vectors=unitvectors(square), bond_linewidth=0.015)
Example block output

Note that the indices showing on the sites are consistent with the indices of the qubits for performing computation. In other words, if we want to do measurement or apply operations on individual sites (qubits), we can refer to the numbering on the atoms for convenience. For more details on how to generate Hamiltonians by using the lattice as an argument, please see the section Hamiltonians.

lattice_vectors(square)
((1.0, 0.0), (0.0, 1.0))
lattice_sites(square)
((0.0, 0.0),)
HoneycombLattice
honeycomb = HoneycombLattice()
Bloqade.plot(generate_sites(honeycomb, 5, 5); vectors=unitvectors(honeycomb), bond_linewidth=0.015)
Example block output
TriangularLattice
triangular = TriangularLattice()
Bloqade.plot(generate_sites(triangular, 8, 8); vectors=unitvectors(triangular), bond_linewidth=0.015)
Example block output
LiebLattice
lieb = LiebLattice()
Bloqade.plot(generate_sites(lieb, 5, 5); vectors=unitvectors(lieb), bond_linewidth=0.015)
Example block output
KagomeLattice
kagome = KagomeLattice()
Bloqade.plot(generate_sites(kagome, 5, 5); vectors=unitvectors(kagome), bond_linewidth=0.015)
Example block output

Sorting Sites and Other Operations on Lattices

We also support different operations on the generated lattices. For instance, one can apply some predefined filters, e.g. rescale_axes, clip_axes, offset_axes, to manipulate atom locations:

atoms = generate_sites(HoneycombLattice(), 3, 5; scale = 4.5)
rescale_axes(atoms, 0.8)
Example block output

where the above operation rescales the coordinates of the original sites by a factor of 0.8.

The code below restricts the atoms sitting in the window (0.0, 5.0), (0.0, 6.0) and throw away those outside this area:

clip_axes(atoms, (0.0, 5.0), (0.0, 6.0))
Example block output

Furthermore, we can shift the origin of the atoms by some vector (5.0, 5.0) simply by typing the code:

offset_axes(atoms, 5.0, 5.0)
Example block output

To sort the atoms by their x-coordinates, one can convert these locations to a MaskedGrid representation of the atoms:

atoms_in_grid = make_grid(atoms)
Example block output

Then one can get the sorted atoms by typing:

sorted_atoms = collect_atoms(atoms_in_grid)
Example block output

Note that the sorting will change the index numbering of the atoms.

You can also delete atoms given their index number:

deleteat!(atoms, 8, 9, 13, 14, 18, 20, 23)
atoms
Example block output

Note that this permanently changes the contents of atoms and just like sorting atoms, will change the index numbering albeit to preserve the integer sequence without gaps.

User-Defined Arbitrary Geometries

One can also generate atoms located at arbitrary positions by directly inputting the coordinates of the atoms:

julia> atom_coordinate = AtomList([(0.0, 0.0), (0, 5), (0, 8), (5, 2), (6, 7), (9, 6)])        ⠀⠀⠀⠀⠀⠀⠀⠀Approximate Atom Positions⠀⠀⠀⠀⠀⠀⠀⠀
        ┌────────────────────────────────────────┐
      8 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
   μm   ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
      0 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
        └────────────────────────────────────────┘0⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀9⠀
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀μm⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

Query Neighbors

One can use make_kdtree to generate a k-d tree data type for the efficient querying of neighborhoods in a low-dimensional space.

tree = make_kdtree(sorted_atoms)
NearestNeighbors.KDTree{StaticArraysCore.SVector{2, Float64}, Distances.Euclidean, Float64, StaticArraysCore.SVector{2, Float64}}
  Number of points: 30
  Dimensions: 2
  Metric: Distances.Euclidean(0.0)
  Reordered: true

The return value is a KDTree instance, which is defined in the package NearestNeigbors. One can use it to query the neighbors of an atom: e.g. one can find the 20 nearest neighbors of the 5-th site by typing:

neighbors = grouped_nearest(tree, 5, 20)
DistanceGroup([5, 8, 2, 3, 6, 11, 4, 10, 9, 7, 13, 14, 1, 12, 16, 17, 15, 19, 20, 18], [1, 2, 5, 9, 11, 14, 16, 17, 18, 19, 20, 21])

The return value is a DistanceGroup instance, and the indices of the second nearest neighbors are:

neighbors[2]
4-element Vector{Int64}:
  6
 11
  4
 10

One can select and display these atoms with the correct labeling by typing:

Bloqade.plot(sorted_atoms[neighbors[2]]; texts=string.(neighbors[2]))
Example block output

It shows the correct second nearest neighbors of the site 5. One can check the docstring of Bloqade.plot to know more about how to customize lattice visualization.

References

BloqadeLattices.AbstractLatticeType
AbstractLattice{D}

Supertype for all D dimensional lattices.

Implementation

lattice_vectors and lattice_sites functions must be defined which should both return an indexable iterable containing the Bravais lattice vectors and lattice sites respectively. (e.g.: GeneralLattice returns a tuple of tuples containing the Bravais lattice vectors and lattice sites).

source
BloqadeLattices.GeneralLatticeType
GeneralLattice{D,K,T} <: AbstractLattice{D}
GeneralLattice(vectors, sites)

The general lattice type for tiling the space. Type parameter D is the dimension, K is the number of sites in a unit cell and T is the data type for coordinates, e.g. Float64. Input arguments are

  • vectors is a vector/tuple of D-tuple. Its length is D, it specifies the Bravais lattice vectors.
  • sites is a vector/tuple of D-tuple. Its length is K, it specifies the sites inside a Bravais cell.
source
BloqadeLattices.SquareLatticeType
struct SquareLattice <: AbstractLattice{2}

Type representing 2D Square Lattice.

Used as an argument of generate_sites function to produce tiling in a square pattern, with number of site repetitions being specified by additional arguments of generate_sites. Square is a 2D Lattice, so there must be two integer arguments as additional inputs.

Example

julia> generate_sites(SquareLattice(), 4, 4)
16-element AtomList{2, Float64}:
 (0.0, 0.0)
 (1.0, 0.0)
 ...
 (2.0, 3.0)
 (3.0, 3.0)

Overriden functions to return lattice vectors and sites exists as lattice_vectors(::SquareLattice) and lattice_sites(::SquareLattice).

source
BloqadeLattices.RectangularLatticeType
struct RectangularLattice <: AbstractLattice{2}

Type representing 2D Rectangular Lattice.

Used as an argument of generate_sites function to produce tiling in a Rectangular pattern, with number of site repetitions being specified by additional arguments of generate_sites. Rectangular is a 2D Lattice, so there must be two integer arguments as additional inputs. This type also enables the user to modify the length of one of the Bravais lattice vectors, by passing a single integer on construction as the aspect ratio.

Example

julia> generate_sites(RectangularLattice(2.0), 2, 2)
4-element AtomList{2, Float64}:
 (0.0, 0.0)
 (1.0, 0.0)
 (0.0, 2.0)
 (1.0, 2.0)

Overriden functions to return lattice vectors and sites exists as lattice_vectors(::RectangularLattice) and lattice_sites(::RectangularLattice).

source
BloqadeLattices.HoneycombLatticeType
struct HoneycombLattice <: AbstractLattice{2}

Type representing 2D Honeycomb Lattice.

Used as an argument of generate_sites function to produce tiling in a honeycomb pattern, with number of site repetitions being specified by additional arguments of generate_sites. Honeycomb is a 2D Lattice, so there must be two integer arguments as additional inputs.

Example

julia> generate_sites(HoneycombLattice(), 5, 5)
50-element AtomList{2, Float64}:
 (0.0, 0.0)
 (0.5, 0.2886751345948129)
...
 (6.0, 3.4641016151377544)
 (6.5, 3.7527767497325675)

Overriden functions to return lattice vectors and sites exists as lattice_vectors(::HoneycombLattice) and lattice_sites(::HoneycombLattice).

source
BloqadeLattices.TriangularLatticeType
struct TriangularLattice <: AbstractLattice{2}

Type representing 2D Square Lattice.

Used as an argument of generate_sites function to produce tiling in a triangle pattern, with number of site repetitions being specified by additional arguments of generate_sites. Triangle is a 2D Lattice, so there must be two integer arguments as additional inputs.

Example

julia> generate_sites(TriangularLattice(), 3, 3)
9-element AtomList{2, Float64}:
 (0.0, 0.0)
 (1.0, 0.0)
 ...
 (2.0, 1.7320508075688772)
 (3.0, 1.7320508075688772)

Overriden functions to return lattice vectors and sites exists as lattice_vectors(::TriangularLattice) and lattice_sites(::TriangularLattice).

source
BloqadeLattices.ChainLatticeType
struct ChainLattice <: AbstractLattice{1}

Type representing 1D Chain Lattice.

Used as an argument of generate_sites function to produce tiling in a chain pattern, with number of site repetitions being specified by the additional argument of generate_sites. Chain is a 1D Lattice, so there must be one integer argument as additional inputs.

Example

julia> generate_sites(ChainLattice(), 5)
5-element AtomList{1, Float64}:
 (0.0,)
 (1.0,)
 (2.0,)
 (3.0,)
 (4.0,)

Overriden functions to return lattice vectors and sites exists as lattice_vectors(::ChainLattice) and lattice_sites(::ChainLattice).

source
BloqadeLattices.LiebLatticeType
struct LiebLattice <: AbstractLattice{2}

Type representing 2D Lieb Lattice.

Used as an argument of generate_sites function to produce tiling in a Lieb (square-depleted) pattern, with number of site repetitions being specified by additional arguments of generate_sites. Lieb is a 2D Lattice, so there must be two integer arguments as additional inputs.

Example

julia> generate_sites(LiebLattice(), 3, 3)
27-element AtomList{2, Float64}:
 (0.0, 0.0)
 (0.5, 0.0)
...
 (2.5, 2.0)
 (2.0, 2.5)

Overriden functions to return lattice vectors and sites exists as lattice_vectors(::LiebLattice) and lattice_sites(::LiebLattice).

source
BloqadeLattices.KagomeLatticeType
struct KagomeLattice <: AbstractLattice{2}

Type representing 2D Kagome Lattice.

Used as an argument of generate_sites function to produce tiling in a Kagome pattern, with number of site repetitions being specified by additional arguments of generate_sites. Kagome is a 2D Lattice, so there must be two integer arguments as additional inputs.

Example

julia> generate_sites(KagomeLattice(), 3, 3)
27-element AtomList{2, Float64}:
 (0.0, 0.0)
 (0.25, 0.4330127018922193)
 ...
 (3.25, 2.1650635094610964)
 (3.75, 2.1650635094610964)

Overriden functions to return lattice vectors and sites exists as lattice_vectors(::KagomeLattice) and lattice_sites(::KagomeLattice).

source
BloqadeLattices.lattice_vectorsFunction
lattice_vectors(lattice::AbstractLattice)

Returns Bravais lattice vectors as a D-Tuple of D-Tuple, where D is the space dimension.

source
lattice_vectors(::HoneycombLattice)

Returns the Bravais lattice vectors for a Honeycomb lattice as a Tuple of Tuples containing floats.

The vectors are defined as:

  • 𝐚₁ = (1.0, 0.0)
  • 𝐚₂ = (0.5, 0.5√3)
source
lattice_vectors(::SquareLattice)

Returns the Bravais lattice vectors for a Square lattice as a Tuple of Tuples containing floats.

The vectors are defined as:

  • 𝐚₁ = (1.0, 0.0)
  • 𝐚₂ = (0.0, 1.0)
source
lattice_vectors(::TriangularLattice)

Returns the Bravais lattice vectors for a Triangular lattice as a Tuple of Tuples containing floats.

The vectors are defined as:

  • 𝐚₁ = (1.0, 0.0)
  • 𝐚₂ = (0.5, 0.5√3)
source
lattice_vectors(::ChainLattice)

Returns the Bravais lattice vectors for a Chain lattice as a Tuple of Tuples containing floats.

The vectors are defined as:

  • 𝐚₁ = (1.0,)
source
lattice_vectors(::LiebLattice)

Returns the Bravais lattice vectors for a Lieb lattice as a Tuple of Tuples containing floats.

The vectors are defined as:

  • 𝐚₁ = (1.0, 0.0)
  • 𝐚₂ = (0.0, 1.0)
source
lattice_vectors(::KagomeLattice)

Returns the Bravais lattice vectors for a Kagome lattice as a Tuple of Tuples containing floats.

The vectors are defined as:

  • 𝐚₁ = (1.0, 0.0)
  • 𝐚₂ = (0.5, 0.5√3)
source
lattice_vectors(r::RectangularLattice)

Returns the Bravais lattice vectors for a Rectangular lattice as a Tuple of Tuples containing floats.

The vectors are defined as:

  • 𝐚₁ = (1.0, 0.0)
  • 𝐚₂ = (0.0, r.aspect_ratio), where aspect_ratio is a Float64.
source
lattice_vectors(lattice::BoundedLattice{L,C})

Returns the underlying Bravais lattice vectors of the BoundedLattice

julia> bl = parallelepiped_region(SquareLattice(),(3,0),(0,2);) # create a 2D BoundedLattice

julia> lattice_vectors(bl) # lattice vectors used in Bravais Lattice definition of underlying SquareLattice
((1.0, 0.0), (0.0, 1.0))
source
BloqadeLattices.lattice_sitesFunction
lattice_sites(lattice::AbstractLattice)

Returns sites in a Bravais lattice unit cell as a Tuple of D-Tuple, where D is the space dimension.

source
lattice_sites(::HoneycombLattice)

Returns the Bravais Lattice sites for a Honeycomb lattice as a Tuple of Tuples containing floats.

The sites are defined as:

  • (0.0, 0.0)
  • (0.5, 0.5√3)
source
lattice_sites(::SquareLattice)

Returns the Bravais Lattice sites for a Square lattice as a Tuple of Tuples containing floats.

The sites are defined as:

  • (0.0, 0.0)
source
lattice_sites(::TriangularLattice)

Returns the Bravais Lattice sites for a Triangular lattice as a Tuple of Tuples containing floats.

The sites are defined as:

  • (0.0, 0.0)
source
lattice_sites(::ChainLattice)

Returns the Bravais Lattice sites for a Chain lattice as a Tuple of Tuples containing floats.

The sites are defined as:

  • (0.0,)
source
lattice_sites(::LiebLattice)

Returns the Bravais Lattice sites for a Lieb lattice as a Tuple of Tuples containing floats.

The sites are defined as:

  • (0.0, 0.0)
  • (0.5, 0.0)
  • (0.0, 0.5)
source
lattice_sites(::KagomeLattice)

Returns the Bravais Lattice sites for a Lieb lattice as a Tuple of Tuples containing floats.

The sites are defined as:

  • (0.0, 0.0)
  • (0.25, 0.25√3)
  • (0.75, 0.25√3)
source
lattice_sites(::RectangularLattice)

Returns the Bravais Lattice sites for a Rectangular lattice as a Tuple of Tuples containing floats.

The sites are defined as:

  • (0.0, 0.0)
source
lattice_sites(lattice::BoundedLattice{L,C})

Returns the underlying site vectors that define the unit-cell of the BoundedLattice

julia> bl = parallelepiped_region(SquareLattice(),(3,0),(0,2);) # create a 2D BoundedLattice

julia> lattice_sites(bl) # lattice vectors used in Bravais Lattice definition of underlying SquareLattice
((0.0, 0.0), )
source
BloqadeLattices.dimensionFunction
dimension(::AbstractLattice{D})

Returns the space dimension of target lattice. e.g. ChainLattice is a 1D lattice, hence returns 1.

source
dimension(lattice::BoundedLattice{L,C})

Returns the dimensions of the BoundedLattice (e.g.: 2 for 2D, 3 for 3D)

julia> bl = parallelepiped_region(ChainLattice(),(4,);pbc=true) # create a 1D BoundedLattice

julia> dimension(bl)
1

julia> bl = parallelepiped_region(SquareLattice(),(3,0),(0,2);) # create a 2D BoundedLattice

julia> dimension(bl)
2
source
BloqadeLattices.generate_sitesFunction
generate_sites(lattice::AbstractLattice{D}, repeats::Vararg{Int,D}; scale=1.0)

Returns an AtomList instance by tiling the specified lattice. The tiling repeat the sites of the lattice m times along the first dimension, n times along the second dimension, and so on. scale is a real number that re-scales the lattice constant and atom locations.

source
BloqadeLattices.offset_axesFunction
offset_axes(sites::AtomList{D, T}, offsets::Vararg{T,D}) where {D, T}
offset_axes(offsets...)

Offset the sites by distance specified by offsets.

julia> sites = AtomList([(1.0, 2.0), (10.0, 3.0), (1.0, 12.0), (3.0, 5.0)])
4-element AtomList{2, Float64}:
 (1.0, 2.0)
 (10.0, 3.0)
 (1.0, 12.0)
 (3.0, 5.0)

julia> offset_axes(sites, 1.0, 3.0)
4-element AtomList{2, Float64}:
 (2.0, 5.0)
 (11.0, 6.0)
 (2.0, 15.0)
 (4.0, 8.0)
source
BloqadeLattices.random_dropoutFunction
random_dropout(sites::AtomList{D, T}, ratio::Real) where {D, T}
random_dropout(ratio)

Randomly drop out ratio * number of sites atoms from sites, where ratio ∈ [0, 1].

source
BloqadeLattices.rescale_axesFunction
rescale_axes(sites::AtomList{D, T}, scale::Real) where {D, T}
rescale_axes(scale)

Rescale the sites by a constant scale.

julia> sites = AtomList([(1.0, 2.0), (10.0, 3.0), (1.0, 12.0), (3.0, 5.0)])
4-element AtomList{2, Float64}:
 (1.0, 2.0)
 (10.0, 3.0)
 (1.0, 12.0)
 (3.0, 5.0)

julia> rescale_axes(sites, 2.0)
4-element AtomList{2, Float64}:
 (2.0, 4.0)
 (20.0, 6.0)
 (2.0, 24.0)
 (6.0, 10.0)
source
BloqadeLattices.clip_axesFunction
clip_axes(sites::AtomList{D, T}, bounds::Vararg{Tuple{T,T},D}) where {D, T}
clip_axes(bounds...)

Remove sites out of bounds, where bounds is specified by D D-tuples.

julia> sites = AtomList([(1.0, 2.0), (10.0, 3.0), (1.0, 12.0), (3.0, 5.0)])
4-element AtomList{2, Float64}:
 (1.0, 2.0)
 (10.0, 3.0)
 (1.0, 12.0)
 (3.0, 5.0)

julia> clip_axes(sites, (-5.0, 5.0), (-5.0, 5.0))
2-element AtomList{2, Float64}:
 (1.0, 2.0)
 (3.0, 5.0)
source
BloqadeLattices.MaskedGridType
MaskedGrid{T}
MaskedGrid(xs, ys, mask)

Masked square lattice contains 3 fields, the x-coordinates, y-coordinates and a mask. e.g. MaskedGrid([0.0, 1.0, 3.0], [0.0, 2.0,6.0], Bool[1 0 0; 0 1 1; 0 1 0]) specifies the following lattice:

     y₁   y₂        y₃
     ↓    ↓         ↓
x₁ → ●    ⋅         ●
x₂ → ⋅    ●         ●

x₃ → ⋅    ●         ⋅
source
BloqadeLattices.AtomListType
AtomList{D, T} <: AbstractVector{NTuple{D, T}}
AtomList(atoms::Vector{<:NTuple})

A list of atoms in D dimensional space.

source
BloqadeLattices.make_gridFunction
make_grid(sites::AtomList; atol=...)

Create a MaskedGrid from the sites. It is required by lattice preparation of Rydberg array. Because the grid will sort the sites by rows, we need atol (default value is 10 time sit data precision) determines up to what level of round off error, two atoms belong to the same row.

source
BloqadeLattices.img_atomsFunction
img_atoms(atoms::Union{AtomList, BoundedLattice};
        colors = [DEFAULT_LINE_COLOR[], ...],
        texts = ["1", "2", ...],
        vectors = [],
        format = :svg,
        filename = nothing,
        kwargs...
    )

Plots atoms or bounded_lattice.site_positions with colors specified by colors and texts specified by texts. You will need a VSCode, Pluto notebook or Jupyter notebook to show the image. If you want to write this image to the disk without displaying it in a frontend, please try

julia> img_atoms(generate_sites(SquareLattice(), 5, 5); filename="test.png")

Keyword Arguments

features

  • colors is a vector of colors for nodes
  • texts is a vector of string displayed on nodes
  • vectors is a vector of (startloc, endloc) pair to specify a list of arrows.

IO

  • format can be :svg, :pdf or :png
  • filename can be a filename string with suffix .svg, .png or .pdf

general

  • background_color = DEFAULT_BACKGROUND_COLOR[]
  • scale::Int = 60.0 is the number of pixels per unit length
  • xpad::Float64 = 2.5 is the padding space in x axis
  • ypad::Float64 = 1.5 is the padding space in y axis

axes

  • axes_text_color = DEFAULT_TEXT_COLOR[]
  • axes_text_fontsize::Float64 = 16.0
  • axes_num_of_xticks = 5
  • axes_num_of_yticks = 5
  • axes_x_offset::Float64 = 0.5
  • axes_y_offset::Float64 = 0.5
  • axes_unit::String = "μm"

node

  • node_text_fontsize::Float64 = 16.0
  • node_text_color = DEFAULT_TEXT_COLOR[]
  • node_stroke_color = DEFAULT_LINE_COLOR[]
  • node_stroke_linewidth = 1
  • node_fill_color = DEFAULT_NODE_COLOR[]

bond

  • bond_color = DEFAULT_LINE_COLOR[]
  • bond_linewidth::Float64 = 1.0

blockade

  • blockade_radius::Float64=0, atoms within blockade_radius will be connected by edges.
  • blockade_style::String = "none", can be "none" or "dashed"
  • blockade_stroke_color = DEFAULT_LINE_COLOR[]
  • blockade_fill_color = "transparent"
  • blockade_fill_opacity::Float64 = 0.5
  • blockade_stroke_linewidth = 1.0 # in pt

arrow

  • arrow_linewidth
  • arrow_color
  • arrow_head_length

grid

  • grid_stroke_color="#AAAAAA"
  • grid_stroke_width::Float64=1
  • grid_stroke_style::String="dashed"
source
BloqadeLattices.img_maskedgridFunction
img_maskedgrid(maskedgrid::MaskedGrid;
    colors=[DEFAULT_LINE_COLOR[], ...],
    texts=["1", "2", ...],
    vectors=[],
    format=:svg,
    filename=nothing,
    kwargs...
    )

Draw a maskedgrid with colors specified by colors and texts specified by texts. You will need a VSCode, Pluto notebook or Jupyter notebook to show the image.

Keyword Arguments

features

  • colors is a vector of colors for nodes
  • texts is a vector of string displayed on nodes
  • vectors is a vector of (startloc, endloc) pair to specify a list of arrows.

IO

  • format can be :svg, :pdf or :png
  • filename can be a filename string with suffix .svg, .png or .pdf

general

  • background_color = DEFAULT_BACKGROUND_COLOR[]
  • scale::Int = 60.0 is the number of pixels per unit length
  • xpad::Float64 = 2.5 is the padding space in x axis
  • ypad::Float64 = 1.5 is the padding space in y axis

axes

  • axes_text_color = DEFAULT_TEXT_COLOR[]
  • axes_text_fontsize::Float64 = 16.0
  • axes_num_of_xticks = 5
  • axes_num_of_yticks = 5
  • axes_x_offset::Float64 = 0.5
  • axes_y_offset::Float64 = 0.5
  • axes_unit::String = "μm"

node

  • node_text_fontsize::Float64 = 16.0
  • node_text_color = DEFAULT_TEXT_COLOR[]
  • node_stroke_color = DEFAULT_LINE_COLOR[]
  • node_stroke_linewidth = 1
  • node_fill_color = DEFAULT_NODE_COLOR[]

bond

  • bond_color = DEFAULT_LINE_COLOR[]
  • bond_linewidth::Float64 = 1.0

blockade

  • blockade_radius::Float64=0, atoms within blockade_radius will be connected by edges.
  • blockade_style::String = "none", can be "none" or "dashed"
  • blockade_stroke_color = DEFAULT_LINE_COLOR[]
  • blockade_fill_color = "transparent"
  • blockade_fill_opacity::Float64 = 0.5
  • blockade_stroke_linewidth = 1.0 # in pt

arrow

  • arrow_linewidth
  • arrow_color
  • arrow_head_length

grid

  • grid_stroke_color="#AAAAAA"
  • grid_stroke_width::Float64=1
  • grid_stroke_style::String="dashed"
source
BloqadeLattices.ByDensityType
ByDensity(values; colormap="Grays", vmin=minimum(values), vmax=maximum(values))

For specifying the colors for density plots, where values are densities.

Keyword arguments

  • colormap is a string for specifying the color map, check the documentation of [Colors] package for the detailed description.
  • vmin and vmax are the color range.
source
BloqadeLattices.AbstractRegionType
AbstractRegion{D}

Supertype for all D dimensional regions used to define bounds on lattices.

Implementation

The following should be overriden:

  • Base.in: Returns Bool on whether a point exists in the region
  • Base.mod: Maps points outside the region back into the region
  • distance: Calculates distance between points with periodic boundary conditions enabled
source
BloqadeLattices.ParallelepipedMethod
Parallelepiped(vecs)
Parallelepiped(vecs::T) where {T<:Real}

Define a region (either a line segment, parallelogram, or parallelepiped depending on the dimensions of vecs) using a single value or column vectors in a matrix that can be used to create a BoundedLattice.

julia> Parallelepiped(2.0) # can bound a 1D lattice
Parallelepiped{1, Float64}([2.0;;], [0.5;;])

julia> bounds = zeros((2,2)); # Create 2x2 matrix to store vectors defining 2D region

julia> bounds[:,1] .= (3,3); bounds[:,2] .= (4,0); # Column Vectors define the Parallelogram

julia> Parallelepiped(bounds)
Parallelepiped{2, Float64}([3.0 4.0; 3.0 0.0], [0.0 0.3333333333333333; 0.25 -0.25])
source
BloqadeLattices.ParallelepipedMethod
Parallelepiped(vecs)
Parallelepiped(vecs::T) where {T<:Real}

Define a region (either a line segment, parallelogram, or parallelepiped depending on the dimensions of vecs) using a single value or column vectors in a matrix that can be used to create a BoundedLattice.

julia> Parallelepiped(2.0) # can bound a 1D lattice
Parallelepiped{1, Float64}([2.0;;], [0.5;;])

julia> bounds = zeros((2,2)); # Create 2x2 matrix to store vectors defining 2D region

julia> bounds[:,1] .= (3,3); bounds[:,2] .= (4,0); # Column Vectors define the Parallelogram

julia> Parallelepiped(bounds)
Parallelepiped{2, Float64}([3.0 4.0; 3.0 0.0], [0.0 0.3333333333333333; 0.25 -0.25])
source
BloqadeLattices.distanceFunction
distance(x, y)
distance(region::Parallelepiped{D,T},x,y)

Distance between two points.

If just points x and y are provided, the Euclidean distance is calculated.

If a region is provided, then it is automatically assumed periodic boundary conditions are enabled and the smallest possible distance between the two points is returned.

julia> distance((0.0, 0.0), (1.0, 1.0))
1.4142135623730951

julia> bounds = zeros(2,2); bounds[:,1] .= (3, 0); bounds[:,2] .= (0, 3);

julia> distance(Parallelepiped(bounds), (0.5, 0.5), (2.5, 2.5))
1.4142135623730951
source
distance(lattice::BoundedLattice,x,y)

Returns the distance between two points in the BoundedLattice.

Points x and y can be any iterable and must have the same dimensions as the BoundedLattice (ex: (x,y) for a 2D lattice, (x,y,z) for a 3D lattice).

If the Periodic Boundary Condition option has been set to true for the BoundedLattice, the smallest distance between points (modulo the region) is returned, otherwise the standard Euclidean metric is used.

julia> bl = parallelepiped_region(SquareLattice(), (1,0),(0,1);) # Define 2D BoundedLattice

julia> distance(bl, (0.1, 0.1), (0.5, 1.1)) # distance between two points
1.077032961426901

julia> bl_pbc = parallelepiped_region(SquareLattice(), (1,0),(0,1);pbc=true) # Define 2D BoundedLattice with Periodic Boundary Condition

julia> distance(bl_pbc, (0.1, 0.1), (0.5, 1.1)) # distance with periodic boundary condition enabled
0.4
source
BloqadeLattices.generate_sites_in_regionFunction
generate_sites_in_region(lattice::AbstractLattice{D}, region::AbstractRegion{D})

Generates sites from the lattice that are present in the region.

julia> generate_sites_in_region(ChainLattice(), Parallelepiped(4.0))
4-element Vector{Tuple{Float64}}:
 (0.0,)
 (1.0,)
 (2.0,)
 (3.0,)

julia> bounds = zeros(2,2)
2×2 Matrix{Float64}:
 0.0  0.0
 0.0  0.0

julia> bounds[:,1] .= (0.0, 2.0); bounds[:,2] .= (2.0, 0.0);

julia> generate_sites_in_region(SquareLattice(), Parallelepiped(bounds))
4-element Vector{Tuple{Float64, Float64}}:
 (0.0, 0.0)
 (1.0, 0.0)
 (0.0, 1.0)
 (1.0, 1.0)
source
BloqadeLattices.BoundedLatticeType
struct BoundedLattice{L<:AbstractLattice, R<:AbstractRegion}

Defines a lattice bounded by a region with the option for periodic boundary conditions.

Fields

  • lattice <: AbstractLattice: Lattice to be bounded.
  • region <: AbstractRegion: Region that bounds the underlying lattice.
  • site_positions::AtomList: Positions of the atoms inside region.
  • pbc::Bool: Enable/Disable behavior for Periodic Boundary Conditions.
source
BloqadeLattices.parallelepiped_regionFunction
parallelepiped_region(lattice::AbstractLattice{D},M::Vararg{NTuple{D,Int},D};pbc::Bool=false;scale::Real=1)

Create a BoundedLattice given an existing lattice and tuples defining a parallelogram/paralelepiped /line segment defined by vectors that are integer multiples of the lattice vectors in lattice.

Periodic Boundary Conditions can be enable/disabled via pbc. Tuples must be the same length and quantity as the dimensions of the lattice argument.

julia> parallelepiped_region(SquareLattice(),(2,0),(0,2);pbc=true);

julia> parallelepiped_region(KagomeLattice(),(2,2),(-2,2));
source
BloqadeLattices.two_body_interaction_matrixFunction
two_body_interaction_matrix(f, atoms)

Generates an interaction matrix given a function f that accepts two atom positions at a time and an indexable iterable atoms containing atom positions.

See also rydberg_interaction_matrix

julia> atoms = [(0.0,), (1.0,), (2.0,), (3.0,)]; # 1D chain, can also be AtomList

julia> two_body_interaction_matrix(atoms) do x,y return 1/distance(x,y) end
4×4 UpperTriangular{Float64, Matrix{Float64}}:
 0.0  1.0  0.5  0.333333
  ⋅   0.0  1.0  0.5
  ⋅    ⋅   0.0  1.0
  ⋅    ⋅    ⋅   0.0
source
BloqadeLattices.rydberg_interaction_matrixFunction
rydberg_interaction_matrix(atoms, C::Real)
rydberg_interaction_matrix(lattice::BoundedLattice{L,R},C::Real)

Generate the interaction matrix given an indexable iterable atoms containg atom positions and the Rydberg interaction constant C.

A BoundedLattice can be used in place of atoms which generates the Rydberg interaction matrix for the lattice, factoring in Periodic Boundary Conditions.

See also two_body_interaction_matrix

julia> atoms = [(0.0,), (1.0,), (2.0,), (3.0,)]; # 1D chain of atoms

julia> rydberg_interaction_matrix(atoms, 2π * 862690) # provide Rydberg constant
4×4 UpperTriangular{Float64, Matrix{Float64}}:
 0.0  5.42044e6  84694.4         7435.45
  ⋅   0.0            5.42044e6  84694.4
  ⋅    ⋅             0.0            5.42044e6
  ⋅    ⋅              ⋅             0.0

julia> bl = parallelepiped_region(SquareLattice(),(2,0),(0,2);pbc=true); 

julia> rydberg_interaction_matrix(bl, 2π * 862690)
4×4 UpperTriangular{Float64, Matrix{Float64}}:
 0.0  5.42044e6  5.42044e6  6.77555e5
  ⋅   0.0        6.77555e5  5.42044e6
  ⋅    ⋅         0.0        5.42044e6
  ⋅    ⋅          ⋅         0.0
source