Skip to content

Commit 2771587

Browse files
change Lattice structure
1 parent d3f1313 commit 2771587

File tree

2 files changed

+77
-31
lines changed

2 files changed

+77
-31
lines changed

docs/src/api.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ tracedist
219219
fidelity
220220
```
221221

222+
## [Spin Lattice](@id doc-API:Spin-Lattice)
223+
224+
```@docs
225+
Lattice
226+
SingleSiteOperator
227+
Dissipativeising
228+
```
229+
222230
## [Miscellaneous](@id doc-API:Miscellaneous)
223231

224232
```@docs

src/spin_lattice.jl

Lines changed: 69 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
export Lattice, mb, TFIM, nn, sx, sy, sz, sm, sp, pbc, obc
1+
export Lattice, SingleSiteOperator, DissipativeIsing
22

3-
sx = sigmax()
4-
sy = -sigmay()
5-
sz = -sigmaz()
6-
sm = (sx - 1im * sy) / 2
7-
sp = (sx + 1im * sy) / 2
3+
@doc raw"""
4+
Lattice
85
9-
#Lattice structure
6+
A Julia constructor for a lattice object. The lattice object is used to define the geometry of the lattice. `Nx` and `Ny` are the number of sites in the x and y directions, respectively. `N` is the total number of sites. `lin_idx` is a `LinearIndices` object and `car_idx` is a `CartesianIndices` object, and they are used to efficiently select sites on the lattice.
7+
"""
108
Base.@kwdef struct Lattice{TN<:Integer,TLI<:LinearIndices,TCI<:CartesianIndices}
119
Nx::TN
1210
Ny::TN
@@ -16,47 +14,87 @@ Base.@kwdef struct Lattice{TN<:Integer,TLI<:LinearIndices,TCI<:CartesianIndices}
1614
end
1715

1816
#Definition of many-body operators
19-
function mb(s::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject}, i::Integer, N::Integer) where {T1}
20-
T = s.dims[1]
21-
return QuantumObject(kron(eye(T^(i - 1)), s, eye(T^(N - i))); dims = ntuple(j -> 2, Val(N)))
17+
@doc raw"""
18+
SingleSiteOperator(O::QuantumObject, i::Integer, N::Integer)
19+
20+
A Julia constructor for a single-site operator. `s` is the operator acting on the site. `i` is the site index, and `N` is the total number of sites. The function returns a `QuantumObject` given by ``\\mathbb{1}^{\\otimes (i - 1)} \\otimes \hat{O} \\otimes \\mathbb{1}^{\\otimes (N - i)}``.
21+
"""
22+
function SingleSiteOperator(O::QuantumObject{DT,OperatorQuantumObject}, i::Integer, N::Integer) where DT
23+
T = O.dims[1]
24+
return QuantumObject(kron(eye(T^(i - 1)), O, eye(T^(N - i))); dims = ntuple(j -> 2, Val(N)))
2225
end
23-
mb(s::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject}, i::Integer, latt::Lattice) where {T1} = mb(s, i, latt.N)
24-
mb(s::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject}, row::Integer, col::Integer, latt::Lattice) where {T1} =
25-
mb(s, latt.idx[row, col], latt.N)
26-
mb(s::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject}, x::CartesianIndex, latt::Lattice) where {T1} =
27-
mb(s, latt.idx[x], latt.N)
26+
SingleSiteOperator(O::QuantumObject{DT,OperatorQuantumObject}, i::Integer, latt::Lattice) where DT = SingleSiteOperator(O, i, latt.N)
27+
SingleSiteOperator(O::QuantumObject{DT,OperatorQuantumObject}, row::Integer, col::Integer, latt::Lattice) where DT =
28+
SingleSiteOperator(O, latt.idx[row, col], latt.N)
29+
SingleSiteOperator(O::QuantumObject{DT,OperatorQuantumObject}, x::CartesianIndex, latt::Lattice) where DT =
30+
SingleSiteOperator(O, latt.idx[x], latt.N)
2831

2932
#Definition of nearest-neighbour sites on lattice
30-
pbc(i::Integer, N::Integer) = 1 + (i - 1 + N) % N
31-
obc(i::Integer, N::Integer) = (i >= 1 && i <= N)
32-
pbc(i::Vector{Int}, N::Integer) = pbc.(i, N)
33-
obc(i::Vector{Int}, N::Integer) = filter(x -> obc(x, N), i)
34-
35-
function nn(i::CartesianIndex, latt::Lattice, bc::Function; order::Integer = 1)
36-
row = bc([i[1] + order, i[1] - order], latt.Nx)
37-
col = bc([i[2] + order, i[2] - order], latt.Ny)
33+
periodic_boundary_conditions(i::Integer, N::Integer) = 1 + (i - 1 + N) % N
34+
open_boundary_conditions(i::Integer, N::Integer) = (i >= 1 && i <= N)
35+
periodic_boundary_conditions(i::Vector{Int}, N::Integer) = periodic_boundary_conditions.(i, N)
36+
open_boundary_conditions(i::Vector{Int}, N::Integer) = filter(x -> open_boundary_conditions(x, N), i)
37+
38+
function nearest_neighbor(i::CartesianIndex, latt::Lattice, ::Val{:periodic_bc}; order::Integer = 1)
39+
row = periodic_boundary_conditions([i[1] + order, i[1] - order], latt.Nx)
40+
col = periodic_boundary_conditions([i[2] + order, i[2] - order], latt.Ny)
41+
return vcat([CartesianIndex(r, i[2]) for r in row], [CartesianIndex(i[1], c) for c in col])
42+
end
43+
44+
function nearest_neighbor(i::CartesianIndex, latt::Lattice, ::Val{:open_bc}; order::Integer = 1)
45+
row = periodic_boundary_conditions([i[1] + order, i[1] - order], latt.Nx)
46+
col = periodic_boundary_conditions([i[2] + order, i[2] - order], latt.Ny)
3847
return vcat([CartesianIndex(r, i[2]) for r in row], [CartesianIndex(i[1], c) for c in col])
3948
end
4049

41-
function TFIM(Jx::Real, Jy::Real, Jz::Real, hx::Real, γ::Real, latt::Lattice; bc::Function = pbc, order::Integer = 1)
42-
S = [mb(sm, i, latt) for i in 1:latt.N]
50+
@doc """
51+
DissipativeIsing(Jx::Real, Jy::Real, Jz::Real, hx::Real, hy::Real, hz::Real, γ::Real, latt::Lattice; boundary_condition::Union{Symbol, Val} = Val(:periodic_bc), order::Integer = 1)
52+
53+
A Julia constructor for a dissipative Ising model. The function returns the Hamiltonian
54+
55+
```math
56+
\\hat{H} = \\frac{J_x}{2} \\sum_{\\langle i, j \\rangle} \\hat{\\sigma}_i^x \\hat{\\sigma}_j^x + \\frac{J_y}{2} \\sum_{\\langle i, j \\rangle} \\hat{\\sigma}_i^y \\hat{\\sigma}_j^y + \\frac{J_z}{2} \\sum_{\\langle i, j \\rangle} \\hat{\\sigma}_i^z \\hat{\\sigma}_j^z + h_x \\sum_i \\hat{\\sigma}_i^x
57+
```
58+
59+
and the collapse operators
60+
61+
```math
62+
\\hat{c}_i = \\sqrt{\\gamma} \\hat{\\sigma}_i^-
63+
```
64+
65+
# Arguments
66+
- `Jx::Real`: The coupling constant in the x-direction.
67+
- `Jy::Real`: The coupling constant in the y-direction.
68+
- `Jz::Real`: The coupling constant in the z-direction.
69+
- `hx::Real`: The magnetic field in the x-direction.
70+
- `hy::Real`: The magnetic field in the y-direction.
71+
- `hz::Real`: The magnetic field in the z-direction.
72+
- `γ::Real`: The local dissipation rate.
73+
- `latt::Lattice`: A [`Lattice`](@ref) object that defines the geometry of the lattice.
74+
- `boundary_condition::Union{Symbol, Val}`: The boundary conditions of the lattice. The possible inputs are `periodic_bc` and `open_bc`, for periodic or open boundary conditions, respectively. The default value is `Val(:periodic_bc)`.
75+
- `order::Integer`: The order of the nearest-neighbour sites. The default value is 1.
76+
"""
77+
function DissipativeIsing(Jx::Real, Jy::Real, Jz::Real, hx::Real, hy::Real, hz::Real, γ::Real, latt::Lattice; boundary_condition::Union{Symbol, Val} = Val(:periodic_bc), order::Integer = 1)
78+
S = [SingleSiteOperator(sm, i, latt) for i in 1:latt.N]
4379
c_ops = sqrt(γ) .* S
4480

45-
op_sum(S, i::CartesianIndex) = S[latt.lin_idx[i]] * sum(S[latt.lin_idx[nn(i, latt, bc; order = order)]])
81+
op_sum(S, i::CartesianIndex) = S[latt.lin_idx[i]] * sum(S[latt.lin_idx[nearest_neighbor(i, latt, makeVal(boundary_condition); order = order)]])
4682

4783
H = 0
4884
if (Jx != 0 || hx != 0)
49-
S .= [mb(sx, i, latt) for i in 1:latt.N]
85+
S .= [SingleSiteOperator(sigmax(), i, latt) for i in 1:latt.N]
5086
H += Jx / 2 * mapreduce(i -> op_sum(S, i), +, latt.car_idx) #/2 because we are double counting
5187
H += hx * sum(S)
5288
end
53-
if Jy != 0
54-
S .= [mb(sy, i, latt) for i in 1:latt.N]
89+
if (Jy != 0 || hy != 0)
90+
S .= [SingleSiteOperator(sigmay(), i, latt) for i in 1:latt.N]
5591
H += Jy / 2 * mapreduce(i -> op_sum(S, i), +, latt.car_idx)
92+
H += hy * sum(S)
5693
end
57-
if Jz != 0
58-
S .= [mb(sz, i, latt) for i in 1:latt.N]
94+
if (Jz != 0 || hz != 0)
95+
S .= [SingleSiteOperator(sigmaz(), i, latt) for i in 1:latt.N]
5996
H += Jz / 2 * mapreduce(i -> op_sum(S, i), +, latt.car_idx)
97+
H += hz * sum(S)
6098
end
6199
return H, c_ops
62100
end;

0 commit comments

Comments
 (0)