I am new to TeNPy and currently trying to implement a 1D Heisenberg model with periodic boundary conditions (PBC).
I have read the documentation and searched online, but I have not found a working example that supports PBC with TEBD.
My current code (see below) works fine for open boundary conditions (OBC), but fails to behave correctly when I switch to periodic.
The goal is to simulate time evolution using the TEBD engine as far as possible in time, for a simple real-coefficient 1D Hamiltonian
(Heisenberg spin-1/2 chain). I am primarily interested in understanding dynamics and entanglement spreading.
My (naive?) understanding:
* TEBD applies two-site gates sequentially to nearest neighbours, so I expected that PBC could be handled similarly by wrapping around the chain.
* I realize that issues might arise during contractions for measurements, or perhaps in how the gates are applied across the periodic boundary.
* One intuition I have is that PBC might result in more uniform bond dimension growth across the chain, rather than peaking at the center like in OBC — potentially allowing longer evolution times.
The question:
Has anyone implemented TEBD with periodic boundaries in TeNPy for the Heisenberg model (or similar)?
Is there a known workaround or example that would help?
I would be very grateful for any insights, code snippets, or clarification on whether PBC + TEBD is actually feasible in practice within TeNPy.
Thanks a lot in advance!
Python: Select all
from tenpy.networks.site import SpinHalfSite
from tenpy.models.model import MPOModel, CouplingModel, NearestNeighborModel
from tenpy.models.spins import SpinModel
from tenpy.models.lattice import Chain
from tenpy.tools.params import asConfig
class HeisenbergChain(CouplingModel, NearestNeighborModel, MPOModel):
"""
Hamiltonian model:
H = (sum_{i=1}^n interaction_xx[i] Sx_i kron Sx_{i+1} +
interaction_yy[i] Sy_i kron Sy_{i+1} +
interaction_zz[i] Sz_i kron Sz_{i+1}) +
(sum_{i=1}^n h_x[i] Sx_i + h_z[i] Sz_i)
where Sx, Sy, Sz are spin-half matrices.
"""
def __init__(self, model_params):
model_params = asConfig(model_params, "XXZChain")
# All parameters must be specified.
L = model_params.get("L", None, int)
bc = model_params.get("bc", None, str)
Jx = model_params.get("Jx", None, "real_or_array")
Jy = model_params.get("Jy", None, "real_or_array")
Jz = model_params.get("Jz", None, "real_or_array")
hx = model_params.get("hx", None, "real_or_array")
hz = model_params.get("hz", None, "real_or_array")
assert L >= 2
assert bc in ["open", "periodic"]
site = SpinHalfSite(conserve=None)
lat = Chain(L, site, bc=bc, bc_MPS="finite")
CouplingModel.__init__(self, lat)
self.add_onsite(hz, 0, "Sz")
self.add_onsite(hx, 0, "Sx")
# for i in range(L - 1 if bc == "open" else L):
for i in range(L - 1):
self.add_coupling_term(Jx, i, i + 1, "Sx", "Sx")
self.add_coupling_term(Jy, i, i + 1, "Sy", "Sy")
self.add_coupling_term(Jz, i, i + 1, "Sz", "Sz")
if bc == "periodic":
self.add_coupling_term(Jx, 0, L - 1, "Sx", "Sx")
self.add_coupling_term(Jy, 0, L - 1, "Sy", "Sy")
self.add_coupling_term(Jz, 0, L - 1, "Sz", "Sz")
print(self.lat.pairs)
MPOModel.__init__(self, lat, self.calc_H_MPO())
NearestNeighborModel.__init__(self, lat, self.calc_H_bond())