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)
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)

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)

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)
TriangularLattice
triangular = TriangularLattice()
Bloqade.plot(generate_sites(triangular, 8, 8); vectors=unitvectors(triangular), bond_linewidth=0.015)
LiebLattice
lieb = LiebLattice()
Bloqade.plot(generate_sites(lieb, 5, 5); vectors=unitvectors(lieb), bond_linewidth=0.015)
KagomeLattice
kagome = KagomeLattice()
Bloqade.plot(generate_sites(kagome, 5, 5); vectors=unitvectors(kagome), bond_linewidth=0.015)

Sort 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)

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))

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)

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)

Then one can get the sorted atoms by typing:

sorted_atoms = collect_atoms(atoms_in_grid)

Note that the sorting has changed the index numbering of the atoms.

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)])6-element AtomList{2, Real}:
 (0.0, 0.0)
 (0, 5)
 (0, 8)
 (5, 2)
 (6, 7)
 (9, 6)

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}
  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, 10, 6, 11, 4, 7, 9, 14, 13, 1, 16, 12, 17, 15, 19, 20, 22], [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}:
 10
  6
 11
  4

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

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

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.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::AtomList;
    colors = [DEFAULT_LINE_COLOR[], ...],
    texts = ["1", "2", ...],
    vectors = [],
    format = :svg,
    filename = nothing,
    kwargs...
    )
img_atoms(bounded_lattice::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

  • 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.
  • format can be :svg, :pdf or :png
  • filename can be a filename string with suffix .svg, .png or .pdf

Extra Keyword Arguments

  • background_color = DEFAULT_BACKGROUND_COLOR[]
  • scale::Float64 = 1 is a multiplicative factor to rescale the atom distance for better visualization
  • xpad::Float64 = 2.5 is the padding space in x axis
  • ypad::Float64 = 1.5 is the padding space in y axis
  • unit::Int = 60 is the number of pixel per unit distance

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.1
  • axes_y_offset::Float64 = 0.06
  • 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"
  • 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

  • colors is a vector of colors for nodes
  • texts is a vector of string displayed on nodes
  • vectors is a vector of arrows
  • format can be :svg, :pdf or :png
  • filename can be a filename string with suffix .svg, .png or .pdf

Extra Keyword Arguments

  • background_color = DEFAULT_BACKGROUND_COLOR[]
  • scale::Float64 = 1 is a multiplicative factor to rescale the atom distance for better visualization
  • xpad::Float64 = 2.5 is the padding space in x axis
  • ypad::Float64 = 1.5 is the padding space in y axis
  • unit::Int = 60 is the number of pixel per unit distance

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.1
  • axes_y_offset::Float64 = 0.06
  • 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"
  • 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 Matrix{Float64}:
 0.0  1.0  0.5  0.333333
 0.0  0.0  1.0  0.5
 0.0  0.0  0.0  1.0
 0.0  0.0  0.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 Matrix{Float64}:
 0.0  5.42044e6  84694.4         7435.45
 0.0  0.0            5.42044e6  84694.4
 0.0  0.0            0.0            5.42044e6
 0.0  0.0            0.0            0.0

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

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