def __init__(self, model_param): # model parameters L = get_parameter(model_param, 'L', 2, self.__class__) xi = get_parameter(model_param, 'xi', 0.5, self.__class__) Jxx = get_parameter(model_param, 'Jxx', 1., self.__class__) Jz = get_parameter(model_param, 'Jz', 1.5, self.__class__) hz = get_parameter(model_param, 'hz', 0., self.__class__) conserve = get_parameter(model_param, 'conserve', 'Sz', self.__class__) if xi == 0.: g = 0. elif xi == np.inf: g = 1. else: g = np.exp(-1/(xi)) unused_parameters(model_param, self.__class__) # Define the sites and the lattice, which in this case is a simple uniform chain # of spin 1/2 sites site = SpinHalfSite(conserve=conserve) lat = Chain(L, site, bc_MPS='infinite') # The operators that appear in the Hamiltonian. Standard spin operators are # already defined for the spin 1/2 site, but it is also possible to add new # operators using the add_op method Sz, Sp, Sm, Id = site.Sz, site.Sp, site.Sm, site.Id # yapf:disable # The grid (list of lists) that defines the MPO. It is possible to define the # operators in the grid in the following ways: # 1) NPC arrays, defined above: grid = [[Id, Sp, Sm, Sz, -hz*Sz ], [None, g*Id, None, None, 0.5*Jxx*Sm], [None, None, g*Id, None, 0.5*Jxx*Sp], [None, None, None, g*Id, Jz*Sz ], [None, None, None, None, Id ]] # 2) In the form [("OpName", strength)], where "OpName" is the name of the # operator (e.g. "Sm" for Sm) and "strength" is a number that multiplies it. grid = [[[("Id", 1)], [("Sp",1)], [("Sm",1)], [("Sz",1)], [("Sz", -hz)] ], [None , [("Id",g)], None , None , [("Sm", 0.5*Jxx)]], [None , None , [("Id",g)], None , [("Sp", 0.5*Jxx)]], [None , None , None , [("Id",g)], [("Sz",Jz)] ], [None , None , None , None , [("Id",1)] ]] # 3) It is also possible to write a single "OpName", equivalent to # [("OpName", 1)]. grid = [["Id" , "Sp" , "Sm" , "Sz" , [("Sz", -hz)] ], [None , [("Id",g)], None , None , [("Sm", 0.5*Jxx)]], [None , None , [("Id",g)], None , [("Sp", 0.5*Jxx)]], [None , None , None , [("Id",g)], [("Sz",Jz)] ], [None , None , None , None , "Id" ]] # yapf:enable grids = [grid]*L # Generate the MPO from the grid. Note that it is not necessary to specify # the physical legs and their charges, since the from_grids method can extract # this information from the position of the operators inside the grid. H = MPO.from_grids(lat.mps_sites(), grids, bc='infinite', IdL=0, IdR=-1) MPOModel.__init__(self, lat, H)
def __init__(self, model_params): model_params = asConfig(model_params, "AKLTModel") L = model_params.get('L', 2) site = SpinSite(S=1., conserve='Sz') # lattice bc_MPS = model_params.get('bc_MPS', 'finite') bc = 'open' if bc_MPS == 'finite' else 'periodic' lat = Chain(L, site, bc=bc, bc_MPS=bc_MPS) Sp, Sm, Sz = site.Sp, site.Sm, site.Sz S_dot_S = 0.5 * (kron(Sp, Sm) + kron(Sm, Sp)) + kron(Sz, Sz) S_dot_S_square = npc.tensordot(S_dot_S, S_dot_S, [['(p0*.p1*)'], ['(p0.p1)']]) H_bond = S_dot_S + S_dot_S_square / 3. # P_2 = H_bond * 0.5 + 1/3 * npc.eye_like(S_dot_S) J = model_params.get('J', 1.) H_bond = J * H_bond.split_legs().transpose(['p0', 'p1', 'p0*', 'p1*']) H_bond = [H_bond] * L # H_bond[i] acts on sites (i-1, i) if bc_MPS == "finite": H_bond[0] = None # 7) initialize H_bond (the order of 7/8 doesn't matter) NearestNeighborModel.__init__(self, lat, H_bond) # 9) initialize H_MPO MPOModel.__init__(self, lat, self.calc_H_MPO_from_bond())
def __init__(self, L=10, Jn=1, Jnn=0, hz=0, options={}): # use predefined local Hilbert space and onsite operators site = SpinSite(S=1 / 2, conserve=None) self.L = L lat = Chain(L, site, bc="open", bc_MPS="finite") # define geometry MultiCouplingModel.__init__(self, lat) # add terms of the Hamiltonian; # operators "Sx", "Sy", "Sz" are defined by the SpinSite self.add_coupling(Jn, 0, "Sx", 0, "Sx", 1) self.add_coupling(Jn, 0, "Sy", 0, "Sy", 1) self.add_coupling(Jn, 0, "Sz", 0, "Sz", 1) self.add_multi_coupling( Jnn, [("Sx", -1, 0), ("Sx", 1, 0)] ) #(oper, shift, internal index - it's possible to merge sites together) self.add_multi_coupling(Jnn, [("Sy", -1, 0), ("Sy", 1, 0)]) self.add_multi_coupling(Jnn, [("Sz", -1, 0), ("Sz", 1, 0)]) self.add_onsite(hz, 0, "Sz") # finish initialization MPOModel.__init__(self, lat, self.calc_H_MPO()) self.psi = MPS.from_product_state(self.lat.mps_sites(), [0] * L, "finite") self.options = options self.dmrg_retval = None
def test_InitialStateBuilder(): s0 = site.SpinHalfSite() lat = Chain(10, s0, bc_MPS='finite') psi1 = mps.InitialStateBuilder( lat, { 'method': 'lat_product_state', 'product_state': [['up'], ['down']], 'check_filling': 0.5, 'full_empty': ['up', 'down'], }).run() psi1.test_sanity() psi2 = mps.InitialStateBuilder( lat, { 'method': 'mps_product_state', 'product_state': ['up', 'down'] * 5, 'check_filling': 0.5, 'full_empty': ['up', 'down'], }).run() psi2.test_sanity() assert abs(psi1.overlap(psi2) - 1) < 1.e-14 psi3 = mps.InitialStateBuilder( lat, { 'method': 'fill_where', 'full_empty': ('up', 'down'), 'fill_where': "x_ind % 2 == 0", 'check_filling': 0.5, 'full_empty': ['up', 'down'], }).run() psi3.test_sanity() assert abs(psi1.overlap(psi3) - 1) < 1.e-14 psi4 = mps.InitialStateBuilder(lat, { 'method': 'randomized', 'randomized_from_method': 'lat_product_state', 'product_state': [['up'], ['down']], 'check_filling': 0.5, 'full_empty': ['up', 'down'], }, model_dtype=np.float64).run() assert psi4.dtype == np.float64 assert abs(psi4.overlap(psi1) - 1) > 0.1 # randomizing should lead to small overlap! psi5 = mps.InitialStateBuilder(lat, { 'method': 'randomized', 'randomized_from_method': 'lat_product_state', 'randomize_close_1': True, 'randomize_params': { 'N_steps': 2 }, 'product_state': [['up'], ['down']], 'check_filling': 0.5, 'full_empty': ['up', 'down'], }, model_dtype=np.complex128).run() assert psi5.dtype == np.complex128 assert 1.e-8 < abs(psi5.overlap(psi1) - 1) < 0.1 # but here we randomize only a bit
def __init__(self, model_param): # 0) Read and set parameters. L = get_parameter(model_param, 'L', 1, self.__class__) bc_MPS = get_parameter(model_param, 'bc_MPS', 'finite', self.__class__) t = get_parameter(model_param, 't', 1., self.__class__) alpha = get_parameter(model_param, 'alpha', 1.0, self.__class__) delta = get_parameter(model_param, 'delta', 1.0, self.__class__) beta = get_parameter(model_param, 'beta', 1.0, self.__class__) conserve_fermionic_boson = get_parameter(model_param, \ 'conserve_fermionic_boson', 'Sz', self.__class__) conserve_spin = get_parameter(model_param, 'conserve_spin', None, self.__class__) unused_parameters(model_param, self.__class__) # 1) Sites and lattice. boson_site = SpinHalfSite(conserve=conserve_fermionic_boson, ) bond_spin = SpinHalfSite(conserve=conserve_spin) double_site = DoubleSite(site0=boson_site, site1=bond_spin, label0='0', label1='1', charges='independent') # lat = Lattice(Ls=[1], unit_cell=[bond_spin], order='default', bc_MPS=bc_MPS, # basis=None, positions=None) lat = Chain(L=L, site=double_site, bc_MPS='finite') # 2) Initialize CouplingModel bc_coupling = 'periodic' if bc_MPS == 'infinite' else 'open' CouplingModel.__init__(self, lat, bc_coupling) # 3) Build the Hamiltonian. # 3a) on-site terms self.add_onsite(delta / 2.0, 0, 'Sigmaz1') self.add_onsite(beta, 0, 'Sigmax1') # 3b) coupling terms. # 3bi) standard Bose-Hubbard coupling terms self.add_coupling(-t, 0, 'Sp0', 0, 'Sm0', 1) self.add_coupling(-t, 0, 'Sm0', 0, 'Sp0', 1) # 3bii) coupling on site bosons to bond spin self.add_coupling(-alpha, 0, 'Sp0 Sigmaz1', 0, 'Sm0', 1) self.add_coupling(-alpha, 0, 'Sm0 Sigmaz1', 0, 'Sp0', 1) # 4) Initialize MPO MPOModel.__init__(self, lat, self.calc_H_MPO()) # 5) Initialize H bond # LS: what does this mean? NearestNeighborModel.__init__(self, self.lat, self.calc_H_bond())
def __init__(self, L=2, S=0.5, J=1., Delta=1., hz=0.): spin = SpinSite(S=S, conserve="Sz") # the lattice defines the geometry lattice = Chain(L, spin, bc="open", bc_MPS="finite") CouplingModel.__init__(self, lattice) # add terms of the Hamiltonian self.add_coupling(J * 0.5, 0, "Sp", 0, "Sm", 1) # Sp_i Sm_{i+1} self.add_coupling(J * 0.5, 0, "Sp", 0, "Sm", -1) # Sp_i Sm_{i-1} self.add_coupling(J * Delta, 0, "Sz", 0, "Sz", 1) # (for site dependent prefactors, the strength can be an array) self.add_onsite(-hz, 0, "Sz") # finish initialization # generate MPO for DMRG MPOModel.__init__(self, lat, self.calc_H_MPO()) # generate H_bond for TEBD NearestNeighborModel.__init__(self, lat, self.calc_H_bond())
def __init__(self, L=10, J=1, Y=0, hz=0, options={}): # use predefined local Hilbert space and onsite operators site = SpinSite(S=1, conserve=None) self.L = L lat = Chain(L, site, bc="open", bc_MPS="finite") # define geometry MultiCouplingModel.__init__(self, lat) # add terms of the Hamiltonian; # operators "Sx", "Sy", "Sz" are defined by the SpinSite self.add_coupling(J, 0, "Sx", 0, "Sx", 1) self.add_coupling(J, 0, "Sy", 0, "Sy", 1) self.add_coupling(J, 0, "Sz", 0, "Sz", 1) for oper1 in ['Sx', 'Sy', 'Sz']: for oper2 in ['Sx', 'Sy', 'Sz']: # (\vec S(i) \cdot \vec S(i+1))^2 coupling self.add_multi_coupling(Y, [(oper1, 0, 0),(oper2, 0, 0),\ (oper1, 1, 0),(oper2, 1, 0)] ) #note that there are two operators on one site self.add_onsite(hz, 0, "Sz") # finish initialization MPOModel.__init__(self, lat, self.calc_H_MPO()) self.psi = MPS.from_product_state(self.lat.mps_sites(), [0] * L, "finite") self.options = options self.dmrg_retval = None
from tenpy.networks.mpo import MPO, MPOEnvironment from tenpy.algorithms.truncation import svd_theta # model parameters Jxx, Jz = 1., 1. L = 20 dt = 0.1 cutoff = 1.e-10 print("Jxx={Jxx}, Jz={Jz}, L={L:d}".format(Jxx=Jxx, Jz=Jz, L=L)) print("1) create Arrays for an Neel MPS") site = SpinHalfSite(conserve='Sz') # predefined charges and Sp,Sm,Sz operators p_leg = site.leg chinfo = p_leg.chinfo # make lattice from unit cell and create product state MPS lat = Chain(L, site, bc_MPS='finite') state = ["up", "down"] * (L // 2) + ["up"] * (L % 2) # Neel state print("state = ", state) psi = MPS.from_product_state(lat.mps_sites(), state, lat.bc_MPS) print("2) create an MPO representing the AFM Heisenberg Hamiltonian") # predefined physical spin-1/2 operators Sz, S+, S- Sz, Sp, Sm, Id = site.Sz, site.Sp, site.Sm, site.Id mpo_leg = npc.LegCharge.from_qflat(chinfo, [[0], [2], [-2], [0], [0]]) W_grid = [[Id, Sp, Sm, Sz, None ], [None, None, None, None, 0.5 * Jxx * Sm], [None, None, None, None, 0.5 * Jxx * Sp], [None, None, None, None, Jz * Sz ],