Source code for ed_lgt.models.SU2_model

import numpy as np
from ed_lgt.modeling import LocalTerm, TwoBodyTerm, PlaquetteTerm, QMB_hamiltonian
from ed_lgt.modeling import check_link_symmetry, staggered_mask
from .quantum_model import QuantumModel
from ed_lgt.operators import SU2_dressed_site_operators, SU2_gauge_invariant_states
import logging

logger = logging.getLogger(__name__)
__all__ = ["SU2_Model"]


[docs] class SU2_Model(QuantumModel): def __init__(self, spin, pure_theory, **kwargs): # Initialize base class with the common parameters super().__init__(**kwargs) self.spin = spin self.pure_theory = pure_theory self.staggered_basis = False # Acquire operators self.ops = SU2_dressed_site_operators( self.spin, self.pure_theory, lattice_dim=self.dim ) # Acquire gauge invariant basis and states self.gauge_basis, self.gauge_states = SU2_gauge_invariant_states( self.spin, self.pure_theory, lattice_dim=self.dim ) # Acquire local dimension and lattice label self.get_local_site_dimensions() # GLOBAL SYMMETRIES if self.pure_theory: global_ops = None global_sectors = None else: global_ops = [self.ops["N_tot"]] global_sectors = [self.n_sites] # LINK SYMMETRIES link_ops = [ [self.ops[f"T2_p{d}"], -self.ops[f"T2_m{d}"]] for d in self.directions ] link_sectors = [0 for _ in self.directions] # GET SYMMETRY SECTOR self.get_abelian_symmetry_sector( global_ops=global_ops, global_sectors=global_sectors, link_ops=link_ops, link_sectors=link_sectors, ) self.default_params()
[docs] def build_Hamiltonian(self, coeffs): # Hamiltonian Coefficients self.coeffs = coeffs # CONSTRUCT THE HAMILTONIAN self.H = QMB_hamiltonian(0, self.lvals, self.loc_dims) h_terms = {} # --------------------------------------------------------------------------- # ELECTRIC ENERGY op_name = "E_square" h_terms[op_name] = LocalTerm(self.ops[op_name], op_name, **self.def_params) self.H.Ham += h_terms[op_name].get_Hamiltonian(strength=coeffs["E"]) # ------------------------------------------------------------------------------- # PLAQUETTE TERM: MAGNETIC INTERACTION if self.dim > 1: op_names_list = ["C_px,py", "C_py,mx", "C_my,px", "C_mx,my"] op_list = [self.ops[op] for op in op_names_list] h_terms["plaq_xy"] = PlaquetteTerm( ["x", "y"], op_list, op_names_list, **self.def_params ) self.H.Ham += h_terms["plaq_xy"].get_Hamiltonian( strength=-self.coeffs["B"], add_dagger=True ) if self.dim == 3: # XZ Plane op_names_list = ["C_px,pz", "C_pz,mx", "C_mz,px", "C_mx,mz"] op_list = [self.ops[op] for op in op_names_list] h_terms["plaq_xz"] = PlaquetteTerm( ["x", "z"], op_list, op_names_list, **self.def_params ) self.H.Ham += h_terms["plaq_xz"].get_Hamiltonian( strength=-self.coeffs["B"], add_dagger=True ) # YZ Plane op_names_list = ["C_py,pz", "C_pz,my", "C_mz,py", "C_my,mz"] op_list = [self.ops[op] for op in op_names_list] h_terms["plaq_yz"] = PlaquetteTerm( ["y", "z"], op_list, op_names_list, **self.def_params ) self.H.Ham += h_terms["plaq_yz"].get_Hamiltonian( strength=-self.coeffs["B"], add_dagger=True ) # --------------------------------------------------------------------------- if not self.pure_theory: # ----------------------------------------------------------------------- # STAGGERED MASS TERM for site in ["even", "odd"]: h_terms[f"N_{site}"] = LocalTerm( self.ops["N_tot"], "N_tot", **self.def_params ) self.H.Ham += h_terms[f"N_{site}"].get_Hamiltonian( coeffs[f"m_{site}"], staggered_mask(self.lvals, site) ) # ----------------------------------------------------------------------- # HOPPING for d in self.directions: for site in ["even", "odd"]: op_names_list = [f"Qp{d}_dag", f"Qm{d}"] op_list = [self.ops[op] for op in op_names_list] # Define the Hamiltonian term h_terms[f"{d}_hop_{site}"] = TwoBodyTerm( d, op_list, op_names_list, **self.def_params ) mask = staggered_mask(self.lvals, site) self.H.Ham += h_terms[f"{d}_hop_{site}"].get_Hamiltonian( strength=coeffs[f"t{d}_{site}"], add_dagger=True, mask=mask, )
[docs] def check_symmetries(self): # CHECK LINK SYMMETRIES for ax in self.directions: check_link_symmetry( ax, self.obs_list[f"T2_p{ax}"], self.obs_list[f"T2_m{ax}"], value=0, sign=-1, )
[docs] def overlap_QMB_state(self, name): if name == "V": s1, s2, L, R = 0, 4, 0, 2 elif name == "PV": s1, s2, L, R = 1, 5, 1, 1 elif name == "M": s1, s2, L, R = 3, 2, 1, 1 config_state = [s1 if ii % 2 == 0 else s2 for ii in range(self.n_sites)] if self.has_obc[0]: config_state[0] = L config_state[-1] = R config_state = config_state return np.array(config_state)