@@ -30,27 +30,45 @@ using ITensors, ITensorMPS, ITensorMPOConstruction
3030↑ = true
3131
3232function create_op_cache_vec (sites:: Vector{<:Index} ):: OpCacheVec
33- operatorNames = [" I" , " Cdn" , " Cup" , " Cdagdn" , " Cdagup" , " Ndn" , " Nup" ,
34- " Cup * Cdn" , " Cup * Cdagdn" , " Cup * Ndn" ,
35- " Cdagup * Cdn" , " Cdagup * Cdagdn" , " Cdagup * Ndn" ,
36- " Nup * Cdn" , " Nup * Cdagdn" , " Nup * Ndn" ]
33+ operatorNames = [
34+ " I" ,
35+ " Cdn" ,
36+ " Cup" ,
37+ " Cdagdn" ,
38+ " Cdagup" ,
39+ " Ndn" ,
40+ " Nup" ,
41+ " Cup * Cdn" ,
42+ " Cup * Cdagdn" ,
43+ " Cup * Ndn" ,
44+ " Cdagup * Cdn" ,
45+ " Cdagup * Cdagdn" ,
46+ " Cdagup * Ndn" ,
47+ " Nup * Cdn" ,
48+ " Nup * Cdagdn" ,
49+ " Nup * Ndn" ,
50+ ]
3751
3852 return to_OpCacheVec (sites, [operatorNames for _ in 1 : length (sites)])
3953end
4054
41- function wrap_around (grid_size:: NTuple{N, Int} , k:: CartesianIndex{N} ):: CartesianIndex{N} where {N}
42- CartesianIndex (NTuple {N, Int} (mod1 (k[i], grid_size[i]) for i in 1 : N))
55+ function wrap_around (
56+ grid_size:: NTuple{N,Int} , k:: CartesianIndex{N}
57+ ):: CartesianIndex{N} where {N}
58+ CartesianIndex (NTuple {N,Int} (mod1 (k[i], grid_size[i]) for i in 1 : N))
4359end
4460
45- function opC (j:: CartesianIndex{N} , spin:: Bool , mapping:: Array{Int, N} ):: OpID{UInt8} where {N}
61+ function opC (j:: CartesianIndex{N} , spin:: Bool , mapping:: Array{Int,N} ):: OpID{UInt8} where {N}
4662 return OpID {UInt8} (2 + spin, mapping[wrap_around (size (mapping), j)])
4763end
4864
49- function opCdag (j:: CartesianIndex{N} , spin:: Bool , mapping:: Array{Int, N} ):: OpID{UInt8} where {N}
65+ function opCdag (
66+ j:: CartesianIndex{N} , spin:: Bool , mapping:: Array{Int,N}
67+ ):: OpID{UInt8} where {N}
5068 return OpID {UInt8} (4 + spin, mapping[wrap_around (size (mapping), j)])
5169end
5270
53- function opN (j:: CartesianIndex{N} , spin:: Bool , mapping:: Array{Int, N} ):: OpID{UInt8} where {N}
71+ function opN (j:: CartesianIndex{N} , spin:: Bool , mapping:: Array{Int,N} ):: OpID{UInt8} where {N}
5472 return OpID {UInt8} (6 + spin, mapping[wrap_around (size (mapping), j)])
5573end
5674
6886function merge_sorted_ops (ops:: AbstractVector{OpID{UInt8}} ):: Int
6987 ITensorMPOConstruction. for_equal_sites (ops) do a, c
7088 local_ops = view (ops, a: c)
71- length (local_ops) == 1 && return
89+ length (local_ops) == 1 && return nothing
7290
7391 b = findfirst (is_spin_dn (op. id) for op in local_ops)
7492 isnothing (b) && (b = length (local_ops) + 1 )
@@ -82,7 +100,7 @@ function merge_sorted_ops(ops::AbstractVector{OpID{UInt8}})::Int
82100 @assert length (spin_up_ops) == 2
83101 @assert spin_up_ops[1 ]. id == 5 # # Cdagup
84102 @assert spin_up_ops[2 ]. id == 3 # # Cup
85-
103+
86104 spin_up_op = 7 # # Nup
87105 end
88106
@@ -96,7 +114,7 @@ function merge_sorted_ops(ops::AbstractVector{OpID{UInt8}})::Int
96114 @assert length (spin_dn_ops) == 2
97115 @assert spin_dn_ops[1 ]. id == 4 # # Cdagdn
98116 @assert spin_dn_ops[2 ]. id == 2 # # Cdn
99-
117+
100118 spin_dn_op = 6 # # Ndn
101119 end
102120
@@ -124,9 +142,11 @@ end;
124142# ## General helper code
125143
126144# # Function to construct the momentum conserving site indices
127- function sites_from_grid (mapping:: Array{Int} , conserve_momentum:: Bool ):: Vector{ITensors.QNIndex}
145+ function sites_from_grid (
146+ mapping:: Array{Int} , conserve_momentum:: Bool
147+ ):: Vector{ITensors.QNIndex}
128148 ! conserve_momentum && return siteinds (" Electron" , length (mapping); conserve_qns= true )
129-
149+
130150 spatial_dimension = ndims (mapping)
131151 @assert 1 <= spatial_dimension <= 2
132152
@@ -136,19 +156,19 @@ function sites_from_grid(mapping::Array{Int}, conserve_momentum::Bool)::Vector{I
136156 k = only (loc)
137157 L = length (mapping)
138158 qns = [
139- QN ((" Nf" , 0 , - 1 ), (" Sz" , + 0 ), (" Kx" , 0 , L)) => 1 ,
140- QN ((" Nf" , 1 , - 1 ), (" Sz" , + 1 ), (" Kx" , k, L)) => 1 ,
141- QN ((" Nf" , 1 , - 1 ), (" Sz" , - 1 ), (" Kx" , k, L)) => 1 ,
142- QN ((" Nf" , 2 , - 1 ), (" Sz" , + 0 ), (" Kx" , 2 * k, L)) => 1
159+ QN ((" Nf" , 0 , - 1 ), (" Sz" , + 0 ), (" Kx" , 0 , L)) => 1 ,
160+ QN ((" Nf" , 1 , - 1 ), (" Sz" , + 1 ), (" Kx" , k, L)) => 1 ,
161+ QN ((" Nf" , 1 , - 1 ), (" Sz" , - 1 ), (" Kx" , k, L)) => 1 ,
162+ QN ((" Nf" , 2 , - 1 ), (" Sz" , + 0 ), (" Kx" , 2 * k, L)) => 1 ,
143163 ]
144164 else
145165 kx, ky = Tuple (loc)
146166 Lx, Ly = size (mapping)
147167 qns = [
148- QN ((" Nf" , 0 , - 1 ), (" Sz" , + 0 ), (" Kx" , 0 , Lx), (" Ky" , 0 , Ly)) => 1 ,
149- QN ((" Nf" , 1 , - 1 ), (" Sz" , + 1 ), (" Kx" , kx, Lx), (" Ky" , ky, Ly)) => 1 ,
150- QN ((" Nf" , 1 , - 1 ), (" Sz" , - 1 ), (" Kx" , kx, Lx), (" Ky" , ky, Ly)) => 1 ,
151- QN ((" Nf" , 2 , - 1 ), (" Sz" , + 0 ), (" Kx" , 2 * kx, Lx), (" Ky" , 2 * ky, Ly)) => 1
168+ QN ((" Nf" , 0 , - 1 ), (" Sz" , + 0 ), (" Kx" , 0 , Lx), (" Ky" , 0 , Ly)) => 1 ,
169+ QN ((" Nf" , 1 , - 1 ), (" Sz" , + 1 ), (" Kx" , kx, Lx), (" Ky" , ky, Ly)) => 1 ,
170+ QN ((" Nf" , 1 , - 1 ), (" Sz" , - 1 ), (" Kx" , kx, Lx), (" Ky" , ky, Ly)) => 1 ,
171+ QN ((" Nf" , 2 , - 1 ), (" Sz" , + 0 ), (" Kx" , 2 * kx, Lx), (" Ky" , 2 * ky, Ly)) => 1 ,
152172 ]
153173 end
154174
@@ -177,7 +197,7 @@ function my_cospi(x::Rational)
177197 return sgn * cospi (x)
178198end
179199
180- function epsilon (gridSize:: NTuple{N, Int} , k:: CartesianIndex{N} ):: Float64 where {N}
200+ function epsilon (gridSize:: NTuple{N,Int} , k:: CartesianIndex{N} ):: Float64 where {N}
181201 return 2 * sum (my_cospi (2 * k[i] // gridSize[i]) for i in 1 : N)
182202end
183203
@@ -191,16 +211,18 @@ end
191211#
192212# 3. Adding the three-electron terms dominate the runtime of this function, but we can add them in parallel with a simple `Threads.@threads`. Thread safety is handled internally to `add!`.
193213
194- function transcorrelated_fermi_hubbard (t:: Real , U:: Real , J:: Real , mapping:: Array{Int} ; conserve_momentum:: Bool = true ):: Tuple{Vector{ITensors.QNIndex}, OpIDSum}
214+ function transcorrelated_fermi_hubbard (
215+ t:: Real , U:: Real , J:: Real , mapping:: Array{Int} ; conserve_momentum:: Bool = true
216+ ):: Tuple{Vector{ITensors.QNIndex},OpIDSum}
195217 grid_size = size (mapping)
196218 N = length (mapping)
197219
198220 sites = sites_from_grid (mapping, conserve_momentum)
199- os = OpIDSum {6, Float64, UInt8} (
221+ os = OpIDSum {6,Float64,UInt8} (
200222 (J == 0 ) ? N^ 3 + 2 * N : N^ 5 ÷ 2 ,
201- create_op_cache_vec (sites),
223+ create_op_cache_vec (sites),
202224 merge_sorted_ops;
203- abs_tol= 1e-14
225+ abs_tol= 1e-14 ,
204226 )
205227
206228 # # The hopping term
@@ -215,7 +237,9 @@ function transcorrelated_fermi_hubbard(t::Real, U::Real, J::Real, mapping::Array
215237 for q in CartesianIndices (mapping)
216238 for k in CartesianIndices (mapping)
217239 factor = U / N
218- ops = opCdag (p - k, ↑ , mapping), opC (p, ↑ , mapping), opCdag (q + k, ↓ , mapping), opC (q, ↓ , mapping)
240+ ops = opCdag (p - k, ↑ , mapping),
241+ opC (p, ↑ , mapping), opCdag (q + k, ↓ , mapping),
242+ opC (q, ↓ , mapping)
219243 add! (os, factor, ops)
220244 end
221245 end
@@ -227,12 +251,19 @@ function transcorrelated_fermi_hubbard(t::Real, U::Real, J::Real, mapping::Array
227251 for p in CartesianIndices (mapping)
228252 for q in CartesianIndices (mapping)
229253 for k in CartesianIndices (mapping)
230- factor = - t * ((exp (J) - 1 ) * epsilon (grid_size, p - k) + (exp (- J) - 1 ) * epsilon (grid_size, p)) / N
231-
232- ops = opCdag (p - k, ↑ , mapping), opC (p, ↑ , mapping), opCdag (q + k, ↓ , mapping), opC (q, ↓ , mapping)
254+ factor =
255+ - t * (
256+ (exp (J) - 1 ) * epsilon (grid_size, p - k) + (exp (- J) - 1 ) * epsilon (grid_size, p)
257+ ) / N
258+
259+ ops = opCdag (p - k, ↑ , mapping),
260+ opC (p, ↑ , mapping), opCdag (q + k, ↓ , mapping),
261+ opC (q, ↓ , mapping)
233262 add! (os, factor, ops)
234263
235- ops = opCdag (q + k, ↑ , mapping), opC (q, ↑ , mapping), opCdag (p - k, ↓ , mapping), opC (p, ↓ , mapping)
264+ ops = opCdag (q + k, ↑ , mapping),
265+ opC (q, ↑ , mapping), opCdag (p - k, ↓ , mapping),
266+ opC (p, ↓ , mapping)
236267 add! (os, factor, ops)
237268 end
238269 end
@@ -249,17 +280,29 @@ function transcorrelated_fermi_hubbard(t::Real, U::Real, J::Real, mapping::Array
249280 wrap_around (grid_size, q + kp) <= wrap_around (grid_size, s + k - kp) && continue
250281
251282 # # Add up the contributions from the four terms.
252- factor = 2 * t * (cosh (J) - 1 ) / N^ 2 * (
253- + epsilon (grid_size, p - (k - kp)) # # From (q + kp , s + k - kp, s, q)
254- - epsilon (grid_size, p - (s + k - kp - q)) # # From (q + kp , s + k - kp, q, s)
255- - epsilon (grid_size, p - (q + kp - s)) # # From (s + k - kp, q + kp , s, q)
256- + epsilon (grid_size, p - kp) # # From (s + k - kp, q + kp , q, s)
257- )
258-
259- ops = opCdag (p - k, ↑ , mapping), opC (p, ↑ , mapping), opCdag (q + kp, ↓ , mapping), opCdag (s + k - kp, ↓ , mapping), opC (s, ↓ , mapping), opC (q, ↓ , mapping)
283+ factor =
284+ 2 * t * (cosh (J) - 1 ) / N^ 2 * (
285+ + epsilon (grid_size, p - (k - kp)) # # From (q + kp , s + k - kp, s, q)
286+ - epsilon (grid_size, p - (s + k - kp - q)) # # From (q + kp , s + k - kp, q, s)
287+ -
288+ epsilon (grid_size, p - (q + kp - s)) # # From (s + k - kp, q + kp , s, q)
289+ + epsilon (grid_size, p - kp) # # From (s + k - kp, q + kp , q, s)
290+ )
291+
292+ ops = opCdag (p - k, ↑ , mapping),
293+ opC (p, ↑ , mapping),
294+ opCdag (q + kp, ↓ , mapping),
295+ opCdag (s + k - kp, ↓ , mapping),
296+ opC (s, ↓ , mapping),
297+ opC (q, ↓ , mapping)
260298 add! (os, factor, ops)
261299
262- ops = opCdag (q + kp, ↑ , mapping), opCdag (s + k - kp, ↑ , mapping), opC (s, ↑ , mapping), opC (q, ↑ , mapping), opCdag (p - k, ↓ , mapping), opC (p, ↓ , mapping)
300+ ops = opCdag (q + kp, ↑ , mapping),
301+ opCdag (s + k - kp, ↑ , mapping),
302+ opC (s, ↑ , mapping),
303+ opC (q, ↑ , mapping),
304+ opCdag (p - k, ↓ , mapping),
305+ opC (p, ↓ , mapping)
263306 add! (os, factor, ops)
264307 end
265308 end
285328
286329function epsilon_mapping (grid_size:: Tuple ):: Array{Int}
287330 kAndEps = vec ([(k, epsilon (grid_size, k)) for k in each_grid_site (grid_size)])
288- sort! (kAndEps, by = (kAndEps) -> kAndEps[2 ])
289-
331+ sort! (kAndEps; by= (kAndEps) -> kAndEps[2 ])
332+
290333 mapping = zeros (Int, grid_size... )
291334 for (i, (k, eps)) in enumerate (kAndEps)
292335 mapping[k] = i
@@ -297,10 +340,10 @@ end
297340
298341function bipartite_mapping (grid_size)
299342 @assert all (mod (dim, 2 ) == 0 for dim in grid_size)
300-
343+
301344 mapping = zeros (Int, grid_size... )
302345
303- blocks = Dict {Float64, Vector{NTuple{2, CartesianIndex}}} ()
346+ blocks = Dict {Float64,Vector{NTuple{2,CartesianIndex}}} ()
304347 offset = CartesianIndex ([dim ÷ 2 for dim in grid_size]. .. )
305348 for (i, loc) in enumerate (CartesianIndices (mapping))
306349 partnerLoc = wrap_around (grid_size, loc + offset)
@@ -320,7 +363,7 @@ function bipartite_mapping(grid_size)
320363
321364 eps = max (eps, epsPartner)
322365
323- block = get! (blocks, eps, Vector {NTuple{2, CartesianIndex}} ())
366+ block = get! (blocks, eps, Vector {NTuple{2,CartesianIndex}} ())
324367 if pair ∉ block
325368 push! (block, pair)
326369 end
@@ -345,7 +388,9 @@ for grid_size in ((2, 2), (6, 6))
345388 let t = 1 , U = 4 , J = - 0.5 , mapping = bipartite_mapping (grid_size)
346389 @time " Constructing OpIDSum" sites, os = transcorrelated_fermi_hubbard (t, U, J, mapping)
347390 reset_timer! ()
348- @time " Constructing MPO" H = MPO_new (os, sites; combine_qn_sectors= true , output_level= 0 , check_for_errors= false )
391+ @time " Constructing MPO" H = MPO_new (
392+ os, sites; combine_qn_sectors= true , output_level= 0 , check_for_errors= false
393+ )
349394 grid_size != (2 , 2 ) && print_timer ()
350395 end
351396end
@@ -369,8 +414,8 @@ function call_back(
369414 sites:: Vector{<:Index} ,
370415 llinks:: Vector{<:Index} ,
371416 g:: ITensorMPOConstruction.MPOGraph ,
372- op_cache_vec:: OpCacheVec ) :: Nothing
373-
417+ op_cache_vec:: OpCacheVec ,
418+ ) :: Nothing
374419 n != 18 && return nothing
375420 serialize (" ./mpo.jldump" , (n, H, sites, llinks, g, op_cache_vec))
376421 println (" Wrote a checkpoint to ./mpo.jldump" )
@@ -386,15 +431,17 @@ let t = 1, U = 4, J = -0.5, mapping = standard_mapping((6, 6))
386431 MPO_new (os, sites; combine_qn_sectors= true , check_for_errors= false , call_back)
387432 catch e
388433 if e isa InterruptException
389- println (" Caught a InterruptException!" )
434+ println (" Caught a InterruptException!" )
390435 else
391- rethrow (e)
436+ rethrow (e)
392437 end
393438 end
394439
395440 println (" Reading a checkpoint from ./mpo.jldump" )
396441 n, H, sites, llinks, g, op_cache_vec = Serialization. deserialize (" ./mpo.jldump" )
397- H = resume_MPO_construction (Float64, n + 1 , H, sites, llinks, g, op_cache_vec; combine_qn_sectors= true , call_back)
442+ H = resume_MPO_construction (
443+ Float64, n + 1 , H, sites, llinks, g, op_cache_vec; combine_qn_sectors= true , call_back
444+ )
398445 println (" Construction finished!" )
399446 rm (" ./mpo.jldump" )
400447end
404451# Caught a InterruptException!
405452# Reading a checkpoint from ./mpo.jldump
406453# Construction finished!
407- # ````
454+ # ````
0 commit comments