Ejemplo n.º 1
0
def runge_kutta_vs_exact(Hmat, e, c0, nsteps, dt, prop_method="C_RK4",store_freq=500):
    '''
    e, c are the eigenvalue and eigenvector of Hmat, c0 is normalized to 1
    '''
    # runge-kutta
    from ephMPS import RK
    tableau =  RK.runge_kutta_explicit_tableau(prop_method)
    propagation_c = RK.runge_kutta_explicit_coefficient(tableau)

    ct_rk_list = []
    for istep in xrange(nsteps):

        if istep == 0:
            ct_rk = c0
        else:
            termlist = [ct_rk]
            for iterm in xrange(len(propagation_c)-1):
                termlist.append(Hmat.dot(termlist[iterm])-e[0]*termlist[iterm])
            
            ct_rk_new = np.zeros(c0.shape, dtype=np.complex128)
            for iterm in xrange(len(propagation_c)):
                ct_rk_new += termlist[iterm]*(-1.0j*dt)**iterm*propagation_c[iterm]
            
            ct_rk = ct_rk_new
            ct_rk = ct_rk / np.linalg.norm(ct_rk)
        
        ct_rk_list.append(ct_rk)

        if (istep+1) % store_freq == 0:
            autocorr_store(ct_rk_list, istep+1, index=(istep+1), freq=store_freq)
            ct_rk_list = []            

    return ct_rk_list
Ejemplo n.º 2
0
def hybrid_TDDMRG_TDH(mol, J, MPS, WFN, dt, ephtable, thresh=0.,\
        cleanexciton=None, QNargs=None, TDDMRG_prop_method="C_RK4", TDH_prop_method="unitary",
        normalize=1.0):
    '''
    hybrid TDDMRG and TDH solver
    1.gauge is g_k = 0
    '''
    # construct Hamiltonian
    if QNargs is None:
        MPO, MPOdim, MPOQN, MPOQNidx, MPOQNtot, HAM, Etot = construct_hybrid_Ham(
            mol, J, MPS, WFN)
    else:
        MPO, MPOdim, MPOQN, MPOQNidx, MPOQNtot, HAM, Etot = construct_hybrid_Ham(
            mol, J, MPS[0], WFN)
        MPO = [MPO, MPOQN, MPOQNidx, MPOQNtot]
    print "Etot", Etot

    # EOM of coefficient a
    WFN[-1] *= np.exp(Etot / 1.0j * dt)

    # EOM of TDDMRG
    tableau = RK.runge_kutta_explicit_tableau(TDDMRG_prop_method)
    propagation_c = RK.runge_kutta_explicit_coefficient(tableau)
    MPS = tMPS.tMPS(MPS, MPO, dt, ephtable, propagation_c, thresh=thresh, \
           cleanexciton=cleanexciton, QNargs=QNargs, normalize=normalize)

    # EOM of TDH
    # here if TDH also use RK4, then the TDDMRG part should be changed to get
    # t=t_1, t=t_2... wfn and slope k
    if TDH_prop_method == "unitary":
        TDH.unitary_propagation(HAM, WFN, dt)

    return MPS, WFN
Ejemplo n.º 3
0
def thermal_prop(iMPO, HMPO, nsteps, ephtable, thresh=0, temperature=298, \
       prop_method="C_RK4", compress_method="svd", QNargs=None, approxeiHt=None, normalize=None):
    '''
    do imaginary propagation
    '''
    tableau = RK.runge_kutta_explicit_tableau(prop_method)
    propagation_c = RK.runge_kutta_explicit_coefficient(tableau)

    beta = constant.T2beta(temperature)
    print "beta=", beta
    dbeta = beta / float(nsteps)

    if approxeiHt is not None:
        approxeiHpt = ApproxPropagatorMPO(HMPO, -0.5j*dbeta, ephtable, propagation_c,\
                thresh=approxeiHt, compress_method=compress_method, QNargs=QNargs)
    else:
        approxeiHpt = None

    ketMPO = mpslib.add(iMPO, None, QNargs=QNargs)

    it = 0.0
    for istep in xrange(nsteps):
        it += dbeta
        ketMPO = tMPS(ketMPO, HMPO, -0.5j*dbeta, ephtable, propagation_c,thresh=thresh,\
                cleanexciton=1, compress_method=compress_method, QNargs=QNargs,\
                approxeiHt=approxeiHpt, normalize=normalize)

    return ketMPO
Ejemplo n.º 4
0
def wfnPropagation(iMPS, HMPO, nsteps, dt, ephtable, thresh=0, \
        cleanexciton=None, prop_method="C_RK4", compress_method="svd", QNargs=None):
    '''
    simple wavefunction propagation through Runge-Kutta methods
    '''
    tableau = RK.runge_kutta_explicit_tableau(prop_method)
    propagation_c = RK.runge_kutta_explicit_coefficient(tableau)

    ketMPS = mpslib.add(iMPS, None, QNargs=QNargs)
    Hset = []  # energy
    Vset = []  # overlap
    for isteps in xrange(nsteps):
        if isteps != 0:
            ketMPS = tMPS(ketMPS, HMPO, dt, ephtable, propagation_c, thresh=thresh, \
                cleanexciton=cleanexciton, compress_method=compress_method, \
                QNargs=QNargs)

        Hset.append(mpslib.dot(mpslib.conj(ketMPS,QNargs=QNargs), \
                mpslib.mapply(HMPO, ketMPS, QNargs=QNargs), QNargs=QNargs))
        Vset.append(mpslib.dot(mpslib.conj(ketMPS,QNargs=QNargs), \
                ketMPS, QNargs=QNargs))

    return Hset, Vset
Ejemplo n.º 5
0
def TDH(mol,
        J,
        nexciton,
        WFN,
        dt,
        fe,
        fv,
        prop_method="unitary",
        particle="hardcore boson"):
    '''
    time dependent Hartree solver
    1. gauge is g_k = 0
    2. f = fe + fv is DOF
    3. two propagation method: exact and RK, 
    exact is unitary and is practically better than RK4. 
    if dt_exact < 1/4 dt_RK4, exact is definitely better than RK4.
    '''
    f = fe + fv
    assert (fe + fv) == (len(WFN) - 1)

    # EOM of wfn
    if prop_method == "unitary":
        HAM, Etot = construct_H_Ham(mol,
                                    J,
                                    nexciton,
                                    WFN,
                                    fe,
                                    fv,
                                    particle=particle)
        unitary_propagation(HAM, WFN, dt)
    else:
        [RK_a, RK_b, RK_c,
         Nstage] = RK.runge_kutta_explicit_tableau(prop_method)

        klist = []
        for istage in xrange(Nstage):
            WFN_temp = copy.deepcopy(WFN)
            for jterm in xrange(istage):
                for iwfn in xrange(f):
                    WFN_temp[
                        iwfn] += klist[jterm][iwfn] * RK_a[istage][jterm] * dt
            HAM, Etot_check = construct_H_Ham(mol,
                                              J,
                                              nexciton,
                                              WFN_temp,
                                              fe,
                                              fv,
                                              particle=particle)
            if istage == 0:
                Etot = Etot_check

            klist.append(
                [HAM[iwfn].dot(WFN_temp[iwfn]) / 1.0j for iwfn in xrange(f)])

        for iwfn in xrange(f):
            for istage in xrange(Nstage):
                WFN[iwfn] += RK_b[istage] * klist[istage][iwfn] * dt

    # EOM of coefficient a
    print "Etot", Etot
    WFN[-1] *= np.exp(Etot / 1.0j * dt)
    return WFN
Ejemplo n.º 6
0
    def test_RK(self):
        tableau = RK.runge_kutta_explicit_tableau("Forward_Euler")
        vout = RK.runge_kutta_explicit_coefficient(tableau)
        self.assertTrue(np.allclose(vout,[1.0,1.0]))

        tableau = RK.runge_kutta_explicit_tableau("Heun_RK2")
        vout = RK.runge_kutta_explicit_coefficient(tableau)
        self.assertTrue(np.allclose(vout,[1.0,1.0,0.5]))

        tableau = RK.runge_kutta_explicit_tableau("Ralston_RK2")
        vout = RK.runge_kutta_explicit_coefficient(tableau)
        self.assertTrue(np.allclose(vout,[1.0,1.0,0.5]))
        
        tableau = RK.runge_kutta_explicit_tableau("midpoint_RK2")
        vout = RK.runge_kutta_explicit_coefficient(tableau)
        self.assertTrue(np.allclose(vout,[1.0,1.0,0.5]))
        
        tableau = RK.runge_kutta_explicit_tableau("Kutta_RK3")
        vout = RK.runge_kutta_explicit_coefficient(tableau)
        self.assertTrue(np.allclose(vout,[1.,1.,0.5,0.16666667]))

        tableau = RK.runge_kutta_explicit_tableau("C_RK4")
        vout = RK.runge_kutta_explicit_coefficient(tableau)
        self.assertTrue(np.allclose(vout,[1.,1.,0.5,0.16666667,0.04166667]))
        
        tableau = RK.runge_kutta_explicit_tableau("38rule_RK4")
        vout = RK.runge_kutta_explicit_coefficient(tableau)
        self.assertTrue(np.allclose(vout,[1.,1.,0.5,0.16666667,0.04166667]))
Ejemplo n.º 7
0
def FiniteT_emi(mol, pbond, iMPO, HMPO, dipoleMPO, nsteps, dt, \
        ephtable, insteps, thresh=0, temperature=298, prop_method="C_RK4", compress_method="svd",
        QNargs=None):
    '''
    Finite temperature emission, already included in FiniteT_spectra
    '''
    tableau = RK.runge_kutta_explicit_tableau(prop_method)
    propagation_c = RK.runge_kutta_explicit_coefficient(tableau)

    beta = constant.T2beta(temperature)
    ketMPO = thermal_prop(iMPO,
                          HMPO,
                          insteps,
                          ephtable,
                          prop_method=prop_method,
                          thresh=thresh,
                          temperature=temperature,
                          compress_method=compress_method,
                          QNargs=QNargs)

    braMPO = mpslib.add(ketMPO, None, QNargs=QNargs)

    #\Psi e^{\-beta H} \Psi
    Z = mpslib.dot(mpslib.conj(braMPO, QNargs=QNargs), ketMPO, QNargs=QNargs)
    print "partition function Z(beta)/Z(0)", Z

    AketMPO = mpslib.mapply(dipoleMPO, ketMPO, QNargs=QNargs)

    autocorr = []
    t = 0.0
    ketpropMPO, ketpropMPOdim = ExactPropagatorMPO(mol,
                                                   pbond,
                                                   -1.0j * dt,
                                                   QNargs=QNargs)

    dipoleMPOdagger = mpslib.conjtrans(dipoleMPO, QNargs=QNargs)

    if compress_method == "variational":
        braMPO = mpslib.canonicalise(braMPO, 'l', QNargs=QNargs)

    for istep in xrange(nsteps):
        if istep != 0:
            t += dt
            AketMPO = mpslib.mapply(ketpropMPO, AketMPO, QNargs=QNargs)
            braMPO = tMPS(braMPO,
                          HMPO,
                          dt,
                          ephtable,
                          propagation_c,
                          thresh=thresh,
                          cleanexciton=1,
                          compress_method=compress_method,
                          QNargs=QNargs)

        AAketMPO = mpslib.mapply(dipoleMPOdagger, AketMPO, QNargs=QNargs)
        ft = mpslib.dot(mpslib.conj(braMPO, QNargs=QNargs),
                        AAketMPO,
                        QNargs=QNargs)
        autocorr.append(ft / Z)
        autocorr_store(autocorr, istep)

    return autocorr
Ejemplo n.º 8
0
def FiniteT_spectra(spectratype, mol, pbond, iMPO, HMPO, dipoleMPO, nsteps, dt,\
        ephtable, insteps=0, thresh=0, temperature=298,\
        algorithm=2, prop_method="C_RK4", compress_method="svd", QNargs=None, \
        approxeiHt=None, GSshift=0.0, cleanexciton=None, scheme="P&C"):
    '''
    finite temperature propagation
    only has algorithm 2, two way propagator
    '''
    assert algorithm == 2
    assert spectratype in ["abs", "emi"]
    tableau = RK.runge_kutta_explicit_tableau(prop_method)
    propagation_c = RK.runge_kutta_explicit_coefficient(tableau)

    beta = constant.T2beta(temperature)
    print "beta=", beta

    # e^{\-beta H/2} \Psi
    if spectratype == "emi":
        ketMPO = thermal_prop(iMPO, HMPO, insteps, ephtable,\
                prop_method=prop_method, thresh=thresh,\
                temperature=temperature, compress_method=compress_method,\
                QNargs=QNargs, approxeiHt=approxeiHt)
    elif spectratype == "abs":
        thermalMPO, thermalMPOdim = ExactPropagatorMPO(mol, pbond, -beta/2.0,\
                QNargs=QNargs, shift=GSshift)
        ketMPO = mpslib.mapply(thermalMPO, iMPO, QNargs=QNargs)

    #\Psi e^{\-beta H} \Psi
    Z = mpslib.dot(mpslib.conj(ketMPO, QNargs=QNargs), ketMPO, QNargs=QNargs)
    print "partition function Z(beta)/Z(0)", Z

    autocorr = []
    t = 0.0
    exacteiHpt, exacteiHptdim = ExactPropagatorMPO(mol, pbond, -1.0j*dt,\
            QNargs=QNargs, shift=GSshift)
    exacteiHmt, exacteiHmtdim = ExactPropagatorMPO(mol, pbond, 1.0j*dt,\
            QNargs=QNargs, shift=GSshift)

    if spectratype == "abs":
        ketMPO = mpslib.mapply(dipoleMPO, ketMPO, QNargs=QNargs)
    else:
        dipoleMPOdagger = mpslib.conjtrans(dipoleMPO, QNargs=QNargs)
        if QNargs is not None:
            dipoleMPOdagger[1] = [[0] * len(impsdim)
                                  for impsdim in dipoleMPO[1]]
            dipoleMPOdagger[3] = 0
        ketMPO = mpslib.mapply(ketMPO, dipoleMPOdagger, QNargs=QNargs)

    braMPO = mpslib.add(ketMPO, None, QNargs=QNargs)

    if compress_method == "variational":
        ketMPO = mpslib.canonicalise(ketMPO, 'l', QNargs=QNargs)
        braMPO = mpslib.canonicalise(braMPO, 'l', QNargs=QNargs)

    if approxeiHt is not None:
        approxeiHpt = ApproxPropagatorMPO(HMPO, dt, ephtable, propagation_c,\
                thresh=approxeiHt, compress_method=compress_method, QNargs=QNargs)
        approxeiHmt = ApproxPropagatorMPO(HMPO, -dt, ephtable, propagation_c,\
                thresh=approxeiHt, compress_method=compress_method, QNargs=QNargs)
    else:
        approxeiHpt = None
        approxeiHmt = None

    for istep in xrange(nsteps):
        if istep != 0:
            t += dt
            # for emi bra and ket is conjugated
            if istep % 2 == 0:
                braMPO = mpslib.mapply(braMPO, exacteiHpt, QNargs=QNargs)
                braMPO = tMPS(braMPO, HMPO, -dt, ephtable, propagation_c,\
                       thresh=thresh, cleanexciton=1, compress_method=compress_method, \
                       QNargs=QNargs, approxeiHt=approxeiHmt, scheme=scheme,\
                       prefix=scheme+"2")
            else:
                ketMPO = mpslib.mapply(ketMPO, exacteiHmt, QNargs=QNargs)
                ketMPO = tMPS(ketMPO, HMPO, dt, ephtable, propagation_c, \
                       thresh=thresh, cleanexciton=1, compress_method=compress_method, \
                       QNargs=QNargs, approxeiHt=approxeiHpt, scheme=scheme,\
                       prefix=scheme+"1")

        ft = mpslib.dot(mpslib.conj(braMPO, QNargs=QNargs),
                        ketMPO,
                        QNargs=QNargs)
        if spectratype == "emi":
            ft = np.conj(ft)

        wfn_store(braMPO, istep, "braMPO.pkl")
        wfn_store(ketMPO, istep, "ketMPO.pkl")
        autocorr.append(ft / Z)
        autocorr_store(autocorr, istep)

    return autocorr
Ejemplo n.º 9
0
def ZeroTCorr(iMPS, HMPO, dipoleMPO, nsteps, dt, ephtable, thresh=0, \
        cleanexciton=None, algorithm=1, prop_method="C_RK4",\
        compress_method="svd", QNargs=None, approxeiHt=None, scheme="P&C"):
    '''
    the bra part e^iEt is negected to reduce the oscillation
    algorithm:
    algorithm 1 is the only propagte ket in 0, dt, 2dt
    algorithm 2 is propagte bra and ket in 0, dt, 2dt (in principle, with
    same calculation cost, more accurate, because the bra is also entangled,
    the entanglement is not only in ket)
    compress_method:  svd or variational
    cleanexciton: every time step propagation clean the good quantum number to
    discard the numerical error
    thresh: the svd threshold in svd or variational compress
    '''

    AketMPS = mpslib.mapply(dipoleMPO, iMPS, QNargs=QNargs)
    # store the factor and normalize the AketMPS, factor is the length of AketMPS
    factor = mpslib.dot(mpslib.conj(AketMPS, QNargs=QNargs),
                        AketMPS,
                        QNargs=QNargs)
    factor = np.sqrt(np.absolute(factor))
    print "factor", factor
    AketMPS = mpslib.scale(AketMPS, 1. / factor, QNargs=QNargs)

    if compress_method == "variational":
        AketMPS = mpslib.canonicalise(AketMPS, 'l', QNargs=QNargs)
    AbraMPS = mpslib.add(AketMPS, None, QNargs=QNargs)

    autocorr = []
    t = 0.0

    tableau = RK.runge_kutta_explicit_tableau(prop_method)
    propagation_c = RK.runge_kutta_explicit_coefficient(tableau)

    if approxeiHt is not None:
        approxeiHpt = ApproxPropagatorMPO(HMPO, dt, ephtable, propagation_c,\
                thresh=approxeiHt, compress_method=compress_method, QNargs=QNargs)
        approxeiHmt = ApproxPropagatorMPO(HMPO, -dt, ephtable, propagation_c,\
                thresh=approxeiHt, compress_method=compress_method, QNargs=QNargs)
    else:
        approxeiHpt = None
        approxeiHmt = None

    for istep in xrange(nsteps):
        if istep != 0:
            t += dt
            if algorithm == 1:
                AketMPS = tMPS(AketMPS, HMPO, dt, ephtable, propagation_c, thresh=thresh, \
                    cleanexciton=cleanexciton, compress_method=compress_method, \
                    QNargs=QNargs, approxeiHt=approxeiHpt, normalize=1., \
                    scheme=scheme, prefix=scheme)
            if algorithm == 2:
                if istep % 2 == 1:
                    AketMPS = tMPS(AketMPS, HMPO, dt, ephtable, propagation_c, thresh=thresh, \
                        cleanexciton=cleanexciton, compress_method=compress_method, QNargs=QNargs,\
                        approxeiHt=approxeiHpt, normalize=1., scheme=scheme, \
                        prefix=scheme+"1")
                else:
                    AbraMPS = tMPS(AbraMPS, HMPO, -dt, ephtable, propagation_c, thresh=thresh, \
                        cleanexciton=cleanexciton, compress_method=compress_method, QNargs=QNargs,\
                        approxeiHt=approxeiHmt, normalize=1., scheme=scheme,\
                        prefix=scheme+"2")
        ft = mpslib.dot(mpslib.conj(AbraMPS, QNargs=QNargs),
                        AketMPS,
                        QNargs=QNargs) * factor**2
        wfn_store(AbraMPS, istep, str(dt) + str(thresh) + "AbraMPS.pkl")
        wfn_store(AketMPS, istep, str(dt) + str(thresh) + "AketMPS.pkl")

        autocorr.append(ft)
        autocorr_store(autocorr, istep)

    return autocorr