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)
Exemple #2
0
    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())
Exemple #3
0
    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
Exemple #4
0
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
Exemple #5
0
    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())
Exemple #6
0
    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())
Exemple #7
0
    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
Exemple #8
0
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       ],