Skip to content

Commit ee54ec2

Browse files
Fix 3-site SU dt and reduce artificial C4v breaking (#219)
* Fix 3-site SU `dt` and reduce artificial C4v breaking * Renamed `_su_bondx!` to `_su_xbond!` * Changed `get_expham(dt, H)` to `get_expham(H, dt)` Co-authored-by: Lukas Devos <ldevos98@gmail.com>
1 parent 19b8010 commit ee54ec2

File tree

4 files changed

+41
-24
lines changed

4 files changed

+41
-24
lines changed

src/algorithms/time_evolution/evoltools.jl

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"""
2-
get_expham(dt::Number, H::LocalOperator)
2+
get_expham(H::LocalOperator, dt::Number)
33
44
Compute `exp(-dt * op)` for each term `op` in `H`,
55
and combine them into a new LocalOperator.
66
Each `op` in `H` must be a single `TensorMap`.
77
"""
8-
function get_expham(dt::Number, H::LocalOperator)
8+
function get_expham(H::LocalOperator, dt::Number)
99
return LocalOperator(
1010
physicalspace(H), (sites => exp(-dt * op) for (sites, op) in H.terms)...
1111
)
@@ -181,27 +181,38 @@ Obtain the 3-site gate MPO on the southeast cluster at position `[row, col]`
181181
c c+1
182182
```
183183
"""
184-
function _get_gatempo_se(gate::LocalOperator, row::Int, col::Int)
185-
Nr, Nc = size(gate.lattice)
184+
function _get_gatempo_se(ham::LocalOperator, dt::Number, row::Int, col::Int)
185+
Nr, Nc = size(ham)
186186
@assert 1 <= row <= Nr && 1 <= col <= Nc
187-
unit = id(space(gate.terms[1].second, 1))
188-
sites = (
187+
sites = [
189188
CartesianIndex(row, col),
190189
CartesianIndex(row, col + 1),
191190
CartesianIndex(row - 1, col + 1),
192-
)
193-
nb1x = get_gateterm(gate, (sites[1], sites[2]))
194-
nb1y = get_gateterm(gate, (sites[2], sites[3]))
195-
nb2 = get_gateterm(gate, (sites[1], sites[3]))
196-
op = (1 / 2) * (nb1x unit + unit nb1y) + permute(nb2 unit, ((1, 3, 2), (4, 6, 5)))
191+
]
192+
nb1x = get_gateterm(ham, (sites[1], sites[2]))
193+
nb1y = get_gateterm(ham, (sites[2], sites[3]))
194+
nb2 = get_gateterm(ham, (sites[1], sites[3]))
195+
# identity operator at each site
196+
units = map(sites) do site
197+
site_ = CartesianIndex(mod1(site[1], Nr), mod1(site[2], Nc))
198+
return id(physicalspace(ham)[site_])
199+
end
200+
# when iterating through ┘, └, ┌, ┐ clusters in the unit cell,
201+
# NN / NNN bonds are counted 4 / 2 times, respectively.
202+
@tensor Odt[i' j' k'; i j k] :=
203+
-dt * (
204+
(nb1x[i' j'; i j] * units[3][k' k] + units[1][i'; i] * nb1y[j' k'; j k]) / 4 +
205+
(nb2[i' k'; i k] * units[2][j'; j]) / 2
206+
)
207+
op = exp(Odt)
197208
return gate_to_mpo3(op)
198209
end
199210

200211
"""
201212
Construct the 3-site gate MPOs on the southeast cluster
202213
for 3-site simple update on square lattice.
203214
"""
204-
function _get_gatempos_se(gate::LocalOperator)
205-
Nr, Nc = size(gate.lattice)
206-
return collect(_get_gatempo_se(gate, r, c) for r in 1:Nr, c in 1:Nc)
215+
function _get_gatempos_se(ham::LocalOperator, dt::Number)
216+
Nr, Nc = size(ham.lattice)
217+
return collect(_get_gatempo_se(ham, dt, r, c) for r in 1:Nr, c in 1:Nc)
207218
end

src/algorithms/time_evolution/simpleupdate.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Each SU run is converged when the singular value difference becomes smaller than
99
$(TYPEDFIELDS)
1010
"""
1111
struct SimpleUpdate
12-
dt::Float64
12+
dt::Number
1313
tol::Float64
1414
maxiter::Int
1515
trscheme::TensorKit.TruncationScheme
@@ -29,7 +29,7 @@ Simple update of the x-bond `peps.weights[1,r,c]`.
2929
[2,r+1,c] [2,r+1,c+1]
3030
```
3131
"""
32-
function _su_bondx!(
32+
function _su_xbond!(
3333
row::Int,
3434
col::Int,
3535
gate::AbstractTensorMap{T,S,2,2},
@@ -94,7 +94,7 @@ function su_iter(
9494
direction == 1 ? gate : gate_mirrored,
9595
(CartesianIndex(r, 1), CartesianIndex(r, 2)),
9696
)
97-
ϵ = _su_bondx!(r, 1, term, peps2, alg)
97+
ϵ = _su_xbond!(r, 1, term, peps2, alg)
9898
peps2.vertices[rp1, 2] = deepcopy(peps2.vertices[r, 1])
9999
peps2.vertices[rp1, 1] = deepcopy(peps2.vertices[r, 2])
100100
peps2.weights[1, rp1, 2] = deepcopy(peps2.weights[1, r, 1])
@@ -106,7 +106,7 @@ function su_iter(
106106
direction == 1 ? gate : gate_mirrored,
107107
(CartesianIndex(r, c), CartesianIndex(r, c + 1)),
108108
)
109-
ϵ = _su_bondx!(r, c, term, peps2, alg)
109+
ϵ = _su_xbond!(r, c, term, peps2, alg)
110110
end
111111
end
112112
if direction == 2
@@ -128,7 +128,7 @@ function _simpleupdate2site(
128128
)
129129
time_start = time()
130130
# exponentiating the 2-site Hamiltonian gate
131-
gate = get_expham(alg.dt, ham)
131+
gate = get_expham(ham, alg.dt)
132132
wtdiff = 1.0
133133
wts0 = deepcopy(peps.weights)
134134
for count in 1:(alg.maxiter)

src/algorithms/time_evolution/simpleupdate3site.jl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -414,13 +414,13 @@ function su3site_iter(
414414
),
415415
)
416416
peps2 = deepcopy(peps)
417-
for i in 1:2
417+
for i in 1:4
418418
for site in CartesianIndices(peps2.vertices)
419419
r, c = site[1], site[2]
420420
gs = gatempos[i][r, c]
421421
_su3site_se!(r, c, gs, peps2, alg)
422422
end
423-
peps2 = (i == 1) ? rotl90(peps2) : rotr90(peps2)
423+
peps2 = rotl90(peps2)
424424
end
425425
return peps2
426426
end
@@ -432,9 +432,13 @@ function _simpleupdate3site(
432432
peps::InfiniteWeightPEPS, ham::LocalOperator, alg::SimpleUpdate; check_interval::Int=500
433433
)
434434
time_start = time()
435-
gate = get_expham(alg.dt, ham)
436-
# convert gates to 3-site MPOs
437-
gatempos = [_get_gatempos_se(gate), _get_gatempos_se(rotl90(gate))]
435+
# convert Hamiltonian to 3-site exponentiated gate MPOs
436+
gatempos = [
437+
_get_gatempos_se(ham, alg.dt),
438+
_get_gatempos_se(rotl90(ham), alg.dt),
439+
_get_gatempos_se(rot180(ham), alg.dt),
440+
_get_gatempos_se(rotr90(ham), alg.dt),
441+
]
438442
wtdiff = 1.0
439443
wts0 = deepcopy(peps.weights)
440444
for count in 1:(alg.maxiter)

src/operators/localoperator.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ function physicalspace(O::LocalOperator)
105105
return O.lattice
106106
end
107107

108+
Base.size(O::LocalOperator) = size(physicalspace(O))
109+
108110
# Real and imaginary part
109111
# -----------------------
110112
function Base.real(O::LocalOperator)

0 commit comments

Comments
 (0)