Ejemplo n.º 1
0
def FT_DM(mol,
          J,
          nexciton,
          T,
          nsteps,
          particle="hardcore boson",
          prop_method="unitary"):
    '''
    finite temperature thermal equilibrium density matrix by imaginary time TDH
    '''

    DM = []
    fe = 1
    fv = 0

    # initial state infinite T density matrix
    H_el_indep, H_el_dep = Ham_elec(mol, J, nexciton, particle=particle)
    dim = H_el_indep.shape[0]
    DM.append(np.diag([1.0] * dim, k=0))

    nmols = len(mol)
    for imol in xrange(nmols):
        for iph in xrange(mol[imol].nphs):
            dim = mol[imol].ph[iph].H_vib_indep.shape[0]
            DM.append(np.diag([1.0] * dim, k=0))
            fv += 1
    # the coefficent a
    DM.append(1.0)

    # normalize the dm (physical \otimes ancilla)
    mflib.normalize(DM)

    beta = constant.T2beta(T) / 2.0
    dbeta = beta / float(nsteps)

    for istep in xrange(nsteps):
        DM = TDH(mol,
                 J,
                 nexciton,
                 DM,
                 dbeta / 1.0j,
                 fe,
                 fv,
                 prop_method=prop_method,
                 particle=particle)
        mflib.normalize(DM)

    Z = DM[-1]**2
    print "partition function Z=", Z

    # divide by np.sqrt(partition function)
    DM[-1] = 1.0

    return DM
Ejemplo n.º 2
0
    def test_FT_dynamics_TDH(self):

        mol, J = parameter_PBI.construct_mol(4, nphs=10)
        TDH.construct_Ham_vib(mol, hybrid=False)

        nexciton = 0
        T = 2000
        insteps = 1
        DM = TDH.FT_DM(mol, J, nexciton, T, insteps)

        Os = []
        for imol in xrange(len(mol)):
            dipoleO = TDH.construct_onsiteO(mol,
                                            "a^\dagger a",
                                            dipole=False,
                                            sitelist=[imol])
            Os.append(dipoleO)

        dipoleO = TDH.construct_onsiteO(mol,
                                        "a^\dagger",
                                        dipole=True,
                                        sitelist=[0])
        DM[0] = dipoleO.dot(DM[0])
        mflib.normalize(DM)

        nsteps = 300
        dt = 10.0
        fe, fv = 1, 40
        data = TDH.dynamics_TDH(mol,
                                J,
                                1,
                                DM,
                                dt,
                                nsteps,
                                fe,
                                fv,
                                property_Os=Os)

        with open("std_data/TDH/FT_occ10.npy", 'rb') as f:
            std = np.load(f)
        self.assertTrue(np.allclose(data, std))
Ejemplo n.º 3
0
def linear_spectra(spectratype, mol, J, nexciton, WFN, dt, nsteps, fe, fv,\
        E_offset=0.0, prop_method="unitary", particle="hardcore boson", T=0):
    '''
    ZT/FT linear spectra by TDH
    '''

    assert spectratype in ["abs", "emi"]
    assert particle in ["hardcore boson", "fermion"]
    assert (fe + fv) == (len(WFN) - 1)

    nmols = len(mol)

    if spectratype == "abs":
        dipolemat = construct_onsiteO(mol, "a^\dagger", dipole=True)
        nexciton += 1
    elif spectratype == "emi":
        dipolemat = construct_onsiteO(mol, "a", dipole=True)
        nexciton -= 1

    WFNket = copy.deepcopy(WFN)
    WFNket[0] = dipolemat.dot(WFNket[0])

    # normalize ket
    mflib.normalize(WFNket)

    if T == 0:
        WFNbra = copy.deepcopy(WFNket)
    else:
        WFNbra = copy.deepcopy(WFN)

    # normalize bra
    mflib.normalize(WFNbra)

    # check whether the energy is conserved
    def check_conserveE():
        if T == 0:
            Nouse, Etot_bra = construct_H_Ham(mol, J, nexciton, WFNbra, fe, fv)
        else:
            Nouse, Etot_bra = construct_H_Ham(mol, J, 1 - nexciton, WFNbra, fe,
                                              fv)

        Nouse, Etot_ket = construct_H_Ham(mol, J, nexciton, WFNket, fe, fv)

        return Etot_bra, Etot_ket

    Etot_bra0, Etot_ket0 = check_conserveE()

    autocorr = []
    t = 0.0
    for istep in xrange(nsteps):
        if istep != 0:
            t += dt
            if T == 0:
                if istep % 2 == 1:
                    WFNket = TDH(mol,
                                 J,
                                 nexciton,
                                 WFNket,
                                 dt,
                                 fe,
                                 fv,
                                 prop_method=prop_method,
                                 particle=particle)
                else:
                    WFNbra = TDH(mol,
                                 J,
                                 nexciton,
                                 WFNbra,
                                 -dt,
                                 fe,
                                 fv,
                                 prop_method=prop_method,
                                 particle=particle)
            else:
                # FT
                WFNket = TDH(mol,
                             J,
                             nexciton,
                             WFNket,
                             dt,
                             fe,
                             fv,
                             prop_method=prop_method,
                             particle=particle)
                WFNbra = TDH(mol,
                             J,
                             1 - nexciton,
                             WFNbra,
                             dt,
                             fe,
                             fv,
                             prop_method=prop_method,
                             particle=particle)

        # E_offset to add a prefactor
        ft = np.conj(WFNbra[-1]) * WFNket[-1] * np.exp(-1.0j * E_offset * t)
        for iwfn in xrange(fe + fv):
            if T == 0:
                ft *= np.vdot(WFNbra[iwfn], WFNket[iwfn])
            else:
                # FT
                if iwfn == 0:
                    ft *= mflib.exp_value(WFNbra[iwfn], dipolemat.T,
                                          WFNket[iwfn])
                else:
                    ft *= np.vdot(WFNbra[iwfn], WFNket[iwfn])

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

    Etot_bra1, Etot_ket1 = check_conserveE()

    return autocorr, [Etot_bra0, Etot_bra1, Etot_ket0, Etot_ket1]
Ejemplo n.º 4
0
def FT_DM_hybrid_TDDMRG_TDH(mol, J, nexciton, T, nsteps, pbond, ephtable, \
        thresh=0., TDDMRG_prop_method="C_RK4", cleanexciton=None, QNargs=None, space=None):
    '''
    construct the finite temperature density matrix by hybrid TDDMRG/TDH method
    '''
    # initial state infinite T density matrix
    # TDDMRG
    if nexciton == 0:
        DMMPS, DMMPSdim = tMPS.Max_Entangled_GS_MPS(mol,
                                                    pbond,
                                                    norm=True,
                                                    QNargs=QNargs)
        DMMPO = tMPS.hilbert_to_liouville(DMMPS, QNargs=QNargs)
    elif nexciton == 1:
        DMMPO, DMMPOdim = tMPS.Max_Entangled_EX_MPO(mol,
                                                    pbond,
                                                    norm=True,
                                                    QNargs=QNargs)
    DMMPO = mpslib.MPSdtype_convert(DMMPO, QNargs=QNargs)

    # TDH
    DMH = []

    nmols = len(mol)
    for imol in xrange(nmols):
        for iph in xrange(mol[imol].nphs_hybrid):
            dim = mol[imol].ph_hybrid[iph].H_vib_indep.shape[0]
            DMH.append(np.diag([1.0] * dim, k=0))
    # the coefficent a
    DMH.append(1.0)

    mflib.normalize(DMH)

    beta = constant.T2beta(T) / 2.0
    dbeta = beta / float(nsteps)

    for istep in xrange(nsteps):
        if space is None:
            DMMPO, DMH = hybrid_TDDMRG_TDH(mol, J, DMMPO, DMH, dbeta/1.0j, ephtable, \
                    thresh=thresh, cleanexciton=cleanexciton, QNargs=QNargs, \
                    TDDMRG_prop_method=TDDMRG_prop_method, normalize=1.0)
        else:
            MPOprop, HAM, Etot = ExactPropagator_hybrid_TDDMRG_TDH(mol, J, \
                    DMMPO, DMH, -1.0*dbeta, space=space, QNargs=QNargs)
            DMH[-1] *= np.exp(-1.0 * Etot * dbeta)
            TDH.unitary_propagation(HAM, DMH, dbeta / 1.0j)

            DMMPO = mpslib.mapply(MPOprop, DMMPO, QNargs=QNargs)
            # DMMPO is not normalize in the imaginary time domain
            MPOnorm = mpslib.norm(DMMPO, QNargs=QNargs)
            DMMPO = mpslib.scale(DMMPO, 1. / MPOnorm, QNargs=QNargs)

            DMH[-1] *= MPOnorm

        # normlize the dm (physical \otimes ancilla)
        mflib.normalize(DMH)

    # divided by np.sqrt(partition function)
    DMH[-1] = 1.0

    return DMMPO, DMH