Page 1 of 1

Get excited states in different symmetry sectors

Posted: 29 Mar 2021, 19:28
by pfliang
Hello,

While I was looking at the function test_dmrg_excited in test_dmry.py, I noticed the excited states searched by tenpy are all in the same symmetry sector.
I wonder if there is a way to get excited states in other symmetry sectors with tenpy?

Re: Get excited states in different symmetry sectors

Posted: 29 Mar 2021, 21:20
by Johannes
Yes: just run DMRG with an initial state in the symmetry sector you're interested in.
DMRG doesn't switch charge sectors, so the charge sector of the final state is determined by your initial state.

Re: Get excited states in different symmetry sectors

Posted: 30 Mar 2021, 03:12
by pfliang
Thanks a lot for the reply. I did a few tests, it's exactly as what you said. But I found using single site DMRG gives me wrong results. Can you explain why it is so? See the code below.

Code: Select all

def test_dmrg_excited(eps=1.e-12):

    L, g = 8, 1.3
    bc = 'finite'
    model_params = dict(L=L, J=1., g=g, bc_MPS=bc, conserve='parity')
    M = TFIChain(model_params)
    # compare to exact solution
    ED = ExactDiag(M)
    ED.build_full_H_from_mpo()
    ED.full_diagonalization()
    # Note: energies sorted by chargesector (first 0), then ascending -> perfect for comparison
    print("Exact diag: E[:5] = ", ED.E[:5])
    print("Exact diag: (smalles E)[:10] = ", np.sort(ED.E)[:10])

    psi_ED = [ED.V.take_slice(i, 'ps*') for i in range(5)]
    print("charges : ", [psi.qtotal for psi in psi_ED])

    # first DMRG run
    psi0 = mps.MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc=bc)
    dmrg_pars = {
        'N_sweeps_check': 1,
        'lanczos_params': {
            'reortho': False
        },
	    'trunc_params': {
	        'chi_max': 100,
	        'svd_min': 1.e-10
	    },
        'diag_method': 'lanczos',
        'combine': True
    }
    eng0 = dmrg.SingleSiteDMRGEngine(psi0, M, dmrg_pars)
    E0, psi0 = eng0.run()

    # second DMRG run
    # dmrg_pars['orthogonal_to'] = [psi0]
    produc_state = [0] * L
    produc_state[0] = 1
    psi1 = mps.MPS.from_product_state(M.lat.mps_sites(), produc_state, bc=bc)
    eng1 = dmrg.SingleSiteDMRGEngine(psi1, M, dmrg_pars)
    E1, psi1 = eng1.run()

    print("Ground state energy: ", E0, "; First excited state energy: ", E1)
The result is

Code: Select all

Exact diag: E[:5] =  [-11.78491823  -9.44235849  -8.74371507  -8.13069442  -8.0720393 ]
Exact diag: (smalles E)[:10] =  [-11.78491823 -10.92014868 -10.30712804  -9.60848462  -9.44235849
  -8.93680885  -8.74371507  -8.34083256  -8.13069442  -8.0720393 ]
charges :  [array([0]), array([0]), array([0]), array([0]), array([0])]
Ground state energy:  -10.4 ; First excited state energy:  -7.8
For comparison, using two site DMRG gives

Code: Select all

Exact diag: E[:5] =  [-11.78491823  -9.44235849  -8.74371507  -8.13069442  -8.0720393 ]
Exact diag: (smalles E)[:10] =  [-11.78491823 -10.92014868 -10.30712804  -9.60848462  -9.44235849
  -8.93680885  -8.74371507  -8.34083256  -8.13069442  -8.0720393 ]
charges :  [array([0]), array([0]), array([0]), array([0]), array([0])]
Ground state energy:  -11.784918232217056 ; First excited state energy:  -10.920148680807984

Re: Get excited states in different symmetry sectors

Posted: 30 Mar 2021, 21:50
by Johannes
For single-site DMRG to work you need to enable the "mixer" by setting dmrg_params['mixer']=True, otherwise it cannot grow the bond dimension. Be warned that the default mixer_params might still disable the mixer too early for larger/more correlated systems.

I've just released a bugfix version 0.8.4, where I changed the default setting for the mixer paramter to be True for SingleSiteDMRG, such that it turns on the mixer at least initially.