예제 #1
0
def calc_infinite_groundstates(dmrg_params, g=0.1):
    L = 2
    model_params = dict(L=L,
                        J=1.,
                        g=g,
                        bc_MPS='infinite',
                        conserve=None,
                        verbose=0)

    model = TFIChain(model_params)
    plus_x = np.array([1., 1.]) / np.sqrt(2)
    minus_x = np.array([1., -1.]) / np.sqrt(2)
    psi_plus = MPS.from_product_state(model.lat.mps_sites(), [plus_x] * L,
                                      model.lat.bc_MPS)
    psi_minus = MPS.from_product_state(model.lat.mps_sites(), [minus_x] * L,
                                       model.lat.bc_MPS)

    engine_plus = dmrg.TwoSiteDMRGEngine(psi_plus, model, dmrg_params)
    engine_plus.run()
    print("<Sx> =", psi_plus.expectation_value("Sigmax"))
    engine_minus = dmrg.TwoSiteDMRGEngine(psi_minus, model, dmrg_params)
    engine_minus.run()
    print("<Sx> =", psi_minus.expectation_value("Sigmax"))

    data_plus = {'psi': psi_plus}
    data_plus.update(**engine_plus.env.get_initialization_data())
    data_minus = {'psi': psi_minus}
    data_minus.update(**engine_minus.env.get_initialization_data())

    return model, data_plus, data_minus
예제 #2
0
def example_DMRG_heisenberg_xxz_finite(L, Jz, chi, conserve='best', verbose=True):
    print("finite DMRG, Heisenberg XXZ chain")
    print("L={L:d}, Jz={Jz:.2f}".format(L=L, Jz=Jz))
    model_params = dict(L=L, S=0.5, Jx=1., Jy=1., Jz=Jz,
                        bc_MPS='finite', conserve=conserve, verbose=verbose)
    M = SpinModel(model_params)
    product_state = ["up", "down"] * (M.lat.N_sites // 2)
    psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)
    dmrg_params = {
        'mixer': True,  # setting this to True helps to escape local minima
        'max_E_err': 1.e-16,
        'trunc_params': {
            'chi_max': chi,
            'svd_min': 1.e-16
        },
        'verbose': verbose,
    }
    info = dmrg.run(psi, M, dmrg_params)  # the main work...
    E = info['E']
    E = E * 4
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    Sz = psi.expectation_value("Sz")  # Sz instead of Sigma z: spin-1/2 operators!
    mag_z = np.mean(Sz)
    print("<S_z> = [{Sz0:.5f}, {Sz1:.5f}]; mean ={mag_z:.5f}".format(Sz0=Sz[0],
                                                                     Sz1=Sz[1],
                                                                     mag_z=mag_z))
    # note: it's clear that mean(<Sz>) is 0: the model has Sz conservation!
    corrs = psi.correlation_function("Sz", "Sz", sites1=range(10))
    print("correlations <Sz_i Sz_j> =")
    print(corrs)
    return E, psi, M
예제 #3
0
def run_tebd_tfi(L, mindim, g, tf, dt, verbose=False, order=2):
    model_params = dict(L=L,
                        J=1.,
                        g=g,
                        bc_MPS='finite',
                        conserve=None,
                        verbose=verbose)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)
    tebd_params = {
        'order': order,
        'dt': dt,
        'N_steps': int(tf / dt),
        'trunc_params': {
            'trunc_cut': 1e-14,
            'svd_min': 1e-24,
            'chi_max': mindim
            # 'chi_min': mindim
        },
        'verbose': verbose,
    }
    eng = tebd.Engine(psi, M, tebd_params)
    eng.run()
    print(np.amax(psi.chi))
    return psi
예제 #4
0
def DMRG_tf_ising_finite(Lx, Ly, g, verbose=True):
    print("finite DMRG, transverse field Ising model")
    print("Lx={Lx:d}, Ly={Ly:d}, g={g:.2f}".format(Lx=Lx, Ly=Ly, g=g))
    M = TFIModel(
        dict(g=g,
             J=1.,
             lattice='Triangular',
             bc_MPS='finite',
             Lx=Lx,
             Ly=Ly,
             conserve=None,
             verbose=verbose))
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)
    dmrg_params = {
        'mixer': None,
        'max_E_err': 1.e-10,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'verbose': verbose,
        'combine': True
    }
    info = dmrg.run(psi, M, dmrg_params)
    E = info['E']
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    mag_x = np.sum(psi.expectation_value("Sigmax"))
    mag_z = np.sum(psi.expectation_value("Sigmaz"))
    print("magnetization in X = {mag_x:.5f}".format(mag_x=mag_x))
    print("magnetization in Z = {mag_z:.5f}".format(mag_z=mag_z))
    return E, psi, M
예제 #5
0
파일: d_dmrg.py 프로젝트: navyTensor/tenpy
def example_DMRG_finite(L, g):
    print("finite DMRG, L={L:d}, g={g:.2f}".format(L=L, g=g))
    model_params = dict(L=L,
                        J=1.,
                        g=g,
                        bc_MPS='finite',
                        conserve=None,
                        verbose=0)
    M = TFIChain(model_params)
    psi = MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc='finite')
    dmrg_params = {
        'mixer': None,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'max_E_err': 1.e-10,
        'verbose': 1
    }
    dmrg.run(psi, M, dmrg_params)
    E = np.sum(psi.expectation_value(M.H_bond[1:]))
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    if L < 20:  # compare to exact result
        E_exact = tfi_exact.finite_gs_energy(L, 1., g)
        print("Exact diagonalization: E = {E:.13f}".format(E=E_exact))
        print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
예제 #6
0
def test_ToricCode(Lx=1, Ly=2):
    with warnings.catch_warnings():
        warnings.simplefilter('ignore')
        model_params = {'Lx': Lx, 'Ly': Ly}
        M = ToricCode(model_params)
        psi = MPS.from_product_state(M.lat.mps_sites(), [0] * M.lat.N_sites,
                                     bc='infinite')
        dmrg_params = {
            'mixer': True,
            'trunc_params': {
                'chi_max': 10,
                'svd_min': 1.e-10
            },
            'max_E_err': 1.e-10,
            'N_sweeps_check': 4,
            'verbose': 1
        }
        result = dmrg.run(psi, M, dmrg_params)
        E = result['E']
        print("E =", E)
        psi.canonical_form()
        # energy per "cell"=2 -> energy per site in the dual lattice = 1
        assert abs(E - (-1.)) < dmrg_params['max_E_err']
        print("chi=", psi.chi)
        if Ly == 2:
            assert tuple(psi.chi[:4]) == (2, 4, 4, 4)
        assert abs(
            psi.entanglement_entropy(bonds=[0])[0] - np.log(2) *
            (Ly - 1)) < 1.e-5
예제 #7
0
파일: d_dmrg.py 프로젝트: yeon-lee/tenpy
def example_1site_DMRG_tf_ising_infinite(g):
    print("single-site infinite DMRG, transverse field Ising model")
    print("g={g:.2f}".format(g=g))
    model_params = dict(L=2, J=1., g=g, bc_MPS='infinite', conserve=None)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)
    dmrg_params = {
        'mixer': True,  # setting this to True is essential for the 1-site algorithm to work.
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'max_E_err': 1.e-10,
        'combine': True
    }
    eng = dmrg.SingleSiteDMRGEngine(psi, M, dmrg_params)
    E, psi = eng.run()  # equivalent to dmrg.run() up to the return parameters.
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    mag_x = np.mean(psi.expectation_value("Sigmax"))
    mag_z = np.mean(psi.expectation_value("Sigmaz"))
    print("<sigma_x> = {mag_x:.5f}".format(mag_x=mag_x))
    print("<sigma_z> = {mag_z:.5f}".format(mag_z=mag_z))
    print("correlation length:", psi.correlation_length())
    # compare to exact result
    from tfi_exact import infinite_gs_energy
    E_exact = infinite_gs_energy(1., g)
    print("Analytic result: E (per site) = {E:.13f}".format(E=E_exact))
    print("relative error: ", abs((E - E_exact) / E_exact))
예제 #8
0
def test_tebd(bc_MPS, g=0.5):
    L = 2 if bc_MPS == 'infinite' else 6
    #  xxz_pars = dict(L=L, Jxx=1., Jz=3., hz=0., bc_MPS=bc_MPS)
    #  M = XXZChain(xxz_pars)
    # factor of 4 (2) for J (h) to change spin-1/2 to Pauli matrices
    model_pars = dict(L=L, Jx=0., Jy=0., Jz=-4., hx=2. * g, bc_MPS=bc_MPS, conserve=None)
    M = SpinChain(model_pars)
    state = ([[1, -1.], [1, -1.]] * L)[:L]  # pointing in (-x)-direction
    psi = MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS)

    tebd_param = {
        'verbose': 2,
        'dt': 0.01,
        'order': 2,
        'delta_tau_list': [0.1, 1.e-4, 1.e-8],
        'max_error_E': 1.e-9,
        'trunc_params': {
            'chi_max': 50,
            'trunc_cut': 1.e-13
        }
    }
    engine = tebd.Engine(psi, M, tebd_param)
    engine.run_GS()

    print("norm_test", psi.norm_test())
    if bc_MPS == 'finite':
        psi.canonical_form()
        ED = ExactDiag(M)
        ED.build_full_H_from_mpo()
        ED.full_diagonalization()
        psi_ED = ED.groundstate()
        Etebd = np.sum(M.bond_energies(psi))
        Eexact = np.min(ED.E)
        print("E_TEBD={Etebd:.14f} vs E_exact={Eex:.14f}".format(Etebd=Etebd, Eex=Eexact))
        assert (abs((Etebd - Eexact) / Eexact) < 1.e-7)
        ov = npc.inner(psi_ED, ED.mps_to_full(psi), do_conj=True)
        print("compare with ED: overlap = ", abs(ov)**2)
        assert (abs(abs(ov) - 1.) < 1.e-7)

        # Test real time TEBD: should change on an eigenstate
        Sold = np.average(psi.entanglement_entropy())
        for i in range(3):
            engine.run()
        Enew = np.sum(M.bond_energies(psi))
        Snew = np.average(psi.entanglement_entropy())
        assert (abs(Enew - Etebd) < 1.e-8)
        assert (abs(Sold - Snew) < 1.e-5)  # somehow we need larger tolerance here....

    if bc_MPS == 'infinite':
        Etebd = np.average(M.bond_energies(psi))
        Eexact = e0_tranverse_ising(g)
        print("E_TEBD={Etebd:.14f} vs E_exact={Eex:.14f}".format(Etebd=Etebd, Eex=Eexact))

        Sold = np.average(psi.entanglement_entropy())
        for i in range(2):
            engine.run()
        Enew = np.average(M.bond_energies(psi))
        Snew = np.average(psi.entanglement_entropy())
        assert (abs(Etebd - Enew) < 1.e-7)
        assert (abs(Sold - Snew) < 1.e-5)  # somehow we need larger tolerance here....
예제 #9
0
def run_tenpy_tdvp(L, maxdim, tf, verbose=False):
    model_params = dict(L=L,
                        J=1.,
                        g=1,
                        bc_MPS='finite',
                        conserve=None,
                        verbose=verbose)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)

    tdvp_params = {
        'start_time': 0,
        'dt': 0.1,
        'trunc_params': {
            'chi_max': maxdim,
            'svd_min': 0,
            'trunc_cut': None
        }
    }
    tdvp_engine = tdvp.Engine(psi=psi, model=M, TDVP_params=tdvp_params)
    tdvp_engine.run_two_sites(N_steps=int(tf / 0.1))

    return np.amax(psi.chi)
예제 #10
0
def example_DMRG_tf_ising_finite(L, g, h=0, chi=2, verbose=True):
    print("finite DMRG, transverse field Ising model")
    print("L={L:d}, g={g:.2f}, h={h:.2f}".format(L=L, g=g, h=h))
    model_params = dict(L=L, J=1., g=g, bc_MPS='finite', h=h)
    M = IsingChain(model_params)

    # model_params = dict(L=L, J=1., g=g, bc_MPS='finite', conserve=None, verbose=verbose)
    # M = TFIChain(model_params)

    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)
    dmrg_params = {
        'mixer': None,  # setting this to True helps to escape local minima
        'max_E_err': 1.e-16,
        'trunc_params': {
            'chi_max': chi,
            'svd_min': 1.e-16
        },
        'verbose': verbose,
    }
    info = dmrg.run(psi, M, dmrg_params)  # the main work...
    E = info['E']
    print("E = {E:.16f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    mag_x = np.sum(psi.expectation_value("Sigmax"))
    mag_z = np.sum(psi.expectation_value("Sigmaz"))
    print("magnetization in X = {mag_x:.5f}".format(mag_x=mag_x))
    print("magnetization in Z = {mag_z:.5f}".format(mag_z=mag_z))
    return E, psi, M
예제 #11
0
def run_out_of_equilibrium():
    L = 10
    chi = 5
    delta_t = 0.1
    model_params = {
        'L': L,
        'S': 0.5,
        'conserve': 'Sz',
        'Jz': 1.0,
        'Jy': 1.0,
        'Jx': 1.0,
        'hx': 0.0,
        'hy': 0.0,
        'hz': 0.0,
        'muJ': 0.0,
        'bc_MPS': 'finite',
    }

    heisenberg = tenpy.models.spins.SpinChain(model_params)
    product_state = ["up"] * int(L / 2) + ["down"] * (
        L - int(L / 2)
    )  #starting from a product state which is not an eigenstate of the Heisenberg model
    psi = MPS.from_product_state(heisenberg.lat.mps_sites(),
                                 product_state,
                                 bc=heisenberg.lat.bc_MPS,
                                 form='B')

    tdvp_params = {
        'start_time': 0,
        'dt': delta_t,
        'trunc_params': {
            'chi_max': chi,
            'svd_min': 1.e-10,
            'trunc_cut': None
        }
    }
    tdvp_engine = tdvp.Engine(psi=psi,
                              model=heisenberg,
                              TDVP_params=tdvp_params)
    times = []
    S_mid = []
    for i in range(30):
        tdvp_engine.run_two_sites(N_steps=1)
        times.append(tdvp_engine.evolved_time)
        S_mid.append(psi.entanglement_entropy(bonds=[L // 2])[0])
    for i in range(30):
        tdvp_engine.run_one_site(N_steps=1)
        #psi_2=copy.deepcopy(psi)
        #psi_2.canonical_form()
        times.append(tdvp_engine.evolved_time)
        S_mid.append(psi.entanglement_entropy(bonds=[L // 2])[0])
    import matplotlib.pyplot as plt
    plt.figure()
    plt.plot(times, S_mid)
    plt.xlabel('t')
    plt.ylabel('S')
    plt.axvline(x=3.1, color='red')
    plt.text(0.0, 0.0000015, "Two sites update")
    plt.text(3.1, 0.0000015, "One site update")
    plt.show()
예제 #12
0
파일: d_dmrg.py 프로젝트: navyTensor/tenpy
def example_DMRG_infinite(g):
    print("infinite DMRG, g={g:.2f}".format(g=g))
    model_params = dict(L=2,
                        J=1.,
                        g=g,
                        bc_MPS='infinite',
                        conserve=None,
                        verbose=0)
    M = TFIChain(model_params)
    psi = MPS.from_product_state(M.lat.mps_sites(), [0] * 2, bc='infinite')
    dmrg_params = {
        'mixer': True,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'max_E_err': 1.e-10,
        'verbose': 1
    }
    dmrg.run(psi, M, dmrg_params)
    E = np.mean(psi.expectation_value(M.H_bond))
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    print("correlation length:", psi.correlation_length())
    # compare to exact result
    E_exact = tfi_exact.infinite_gs_energy(1., g)
    print("Analytic result: E/L = {E:.13f}".format(E=E_exact))
    print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
예제 #13
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
예제 #14
0
def test_ExpMPOEvolution(bc_MPS, approximation, compression, g=1.5):
    # Test a time evolution against exact diagonalization for finite bc
    dt = 0.01
    if bc_MPS == 'finite':
        L = 6
    else:
        L = 2
    model_pars = dict(L=L,
                      Jx=0.,
                      Jy=0.,
                      Jz=-4.,
                      hx=2. * g,
                      bc_MPS=bc_MPS,
                      conserve=None)
    M = SpinChain(model_pars)
    state = ([[1 / np.sqrt(2), -1 / np.sqrt(2)]] * L
             )  # pointing in (-x)-direction
    state = ['up'] * L  # pointing in (-z)-direction
    psi = MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS)

    options = {
        'dt': dt,
        'N_steps': 1,
        'order': 1,
        'approximation': approximation,
        'compression_method': compression,
        'trunc_params': {
            'chi_max': 30
        }
    }
    eng = mpo_evolution.ExpMPOEvolution(psi, M, options)

    if bc_MPS == 'finite':
        ED = exact_diag.ExactDiag(M)
        ED.build_full_H_from_mpo()
        ED.full_diagonalization()
        psiED = ED.mps_to_full(psi)
        psiED /= psiED.norm()

        UED = ED.exp_H(dt)
        for i in range(30):
            psi = eng.run()
            psiED = npc.tensordot(UED, psiED, ('ps*', [0]))
            psi_full = ED.mps_to_full(psi)
            assert (abs(abs(npc.inner(psiED, psi_full, [0, 0], True)) - 1) <
                    dt)

    if bc_MPS == 'infinite':
        psiTEBD = psi.copy()
        TEBD_params = {'dt': dt, 'N_steps': 1}
        EngTEBD = tebd.Engine(psiTEBD, M, TEBD_params)
        for i in range(30):
            EngTEBD.run()
            psi = eng.run()
            print(psi.norm)
            print(np.abs(psi.overlap(psiTEBD) - 1))
            #This test fails
            assert (abs(abs(psi.overlap(psiTEBD)) - 1) < 1e-2)
예제 #15
0
def main():
    L = 60
    chi = 80
    U = 10.0
    beta = 0.02

    file_name = "U" + str(int(U)) +\
      "_L"+str(L)+\
      "_Ds_ch"+str(chi)+\
      ".pkl"

    verbose_model = 0
    verbose_dmrg = 0

    t = 1.0
    Mu = 16.0
    alpha = 0.5

    cnsrv_bsn = 'N'
    cnsrv_spn = None
    pkl_pack = []

    for ddelta in range(51):
        delta = 0.50 + ddelta * 0.01
        model_params = {
            'n_max': 2,
            'L': L,
            'bc_MPS': 'finite',
            'filling': 0.5,
            't': t,
            'U': U,
            'mu': Mu,
            'alpha': alpha,
            'delta': delta,
            'beta': beta,
            'conserve_boson': cnsrv_bsn,
            'conserve_spin': cnsrv_spn,
            'verbose': verbose_model
        }
        M = BosonSpin(model_params)
        initial_state = [0] * (L // 2) + [2] * (L // 2)
        psi = MPS.from_product_state(M.lat.mps_sites(),
                                     initial_state,
                                     bc='finite')
        dmrg_params = {'mixer': None, 'verbose': verbose_dmrg, \
              'trunc_params': {'chi_max': chi, 'svd_min': 1.e-10}}
        start_time = time.time()
        dmrg.run(psi, M, dmrg_params)
        end_time = time.time()
        print("$\Delta = {a:.04f}$\tDMRG time = {b}".format(a=delta,
                                                            b=end_time -
                                                            start_time))
        pkl_pack += [[psi, model_params, dmrg_params]]

    with open(file_name, 'wb') as g:
        pickle.dump(pkl_pack, g)

    return 0
예제 #16
0
def main():
    L = 80
    delta = 0.9064

    file_name="L"+str(L) + \
      "_D"+str(int(delta*10000))+\
      "E0" + \
      "_CHIall.pkl"

    verbose_model = 0
    verbose_dmrg = 0

    t = 1.0
    alpha = 0.5
    beta = 0.02

    cnsrv_bsn = 'Sz'
    cnsrv_spn = None

    model_params = {
        'L': L,
        'bc_MPS': 'finite',
        't': t,
        'alpha': alpha,
        'delta': delta,
        'beta': beta,
        'conserve_fermionic_boson': cnsrv_bsn,
        'conserve_spin': cnsrv_spn,
        'verbose': verbose_model
    }
    M = FermionOnSpinLattice(model_params)
    initial_state = [0] * (L // 2) + [2] * (L // 2)

    pkl_pack = [model_params, M]

    chi_start = np.arange(10) + 5
    chi_end = np.arange(35) * 2 + 15

    #chis = np.concatenate((chi_start, chi_end))
    # extra chi for 80
    chis = np.arange(10) * 2 + 85
    for chi in chis:
        psi = MPS.from_product_state(M.lat.mps_sites(),
                                     initial_state,
                                     bc='finite')
        dmrg_params = {'mixer': None, 'verbose': verbose_dmrg, \
              'trunc_params': {'chi_max': chi, 'svd_min': 1.e-10}}
        start_time = time.time()
        dmrg.run(psi, M, dmrg_params)
        end_time = time.time()
        print("D max = {c}\tDMRG time = {b}".format(c=chi,
                                                    b=end_time - start_time))
        pkl_pack += [[psi, chi]]

    with open(file_name, 'wb') as g:
        pickle.dump(pkl_pack, g)

    return 0
예제 #17
0
def run(phi_ext=np.linspace(0, 1.0, 11)):
    data = dict(phi_ext=phi_ext, QL=[], ent_spectrum=[])

    model_params = dict(conserve='N',
                        filling=1 / 2.,
                        Lx=1,
                        Ly=3,
                        t=-1.,
                        mu=0,
                        V=1.,
                        phi_ext=0.,
                        bc_MPS='infinite',
                        bc_y='cylinder',
                        verbose=0)
    dmrg_params = {
        'mixer': True,  # setting this to True helps to escape local minima
        'mixer_params': {
            'amplitude': 1.e-5,
            'decay': 1.2,
            'disable_after': 30
        },
        'trunc_params': {
            'svd_min': 1.e-10,
        },
        'lanczos_params': {
            'N_min': 5,
            'N_max': 20
        },
        'chi_list': {
            0: 9,
            10: 49,
            20: 200
        },
        'max_E_err': 1.e-10,
        'max_S_err': 1.e-6,
        'max_sweeps': 150,
        'verbose': 1.,
    }
    prod_state = ['full', 'empty'] * (model_params['Lx'] * model_params['Ly'] * 2 // 2)
    # TODO allow tiling of list in from_product_state...
    eng = None
    for phi in phi_ext:
        print("=" * 100)
        print("phi_ext = ", phi)
        model_params['phi_ext'] = phi
        if eng is None:  # first time in the loop
            M = FermionicHaldaneModel(model_params)
            psi = MPS.from_product_state(M.lat.mps_sites(), prod_state, bc=M.lat.bc_MPS)
            eng = dmrg.EngineCombine(psi, M, dmrg_params)
        else:
            del eng.DMRG_params['chi_list']
            M = FermionicHaldaneModel(model_params)
            eng.init_env(model=M)
        E, psi = eng.run()
        data['QL'].append(psi.average_charge(bond=0)[0])
        data['ent_spectrum'].append(psi.entanglement_spectrum(by_charge=True)[0])
    return data