def test_quasiboson_constructMPO(self): mol = construct_mol([4, 4]) MPS1, MPSdim1, MPSQN1, MPO1, MPOdim1, MPOQN1, MPOQNidx1, MPOQNtot1, ephtable1, pbond1 = \ MPSsolver.construct_MPS_MPO_2(mol, J, procedure[0][0], nexciton, MPOscheme=2) mol = construct_mol([4, 4], [2, 2], [1e-7, 1e-7]) MPS, MPSdim, MPSQN, MPO, MPOdim, MPOQN, MPOQNidx, MPOQNtot, ephtable, pbond = \ MPSsolver.construct_MPS_MPO_2(mol, J, procedure[0][0], nexciton, MPOscheme=2) # merge the decomposed MPO MPOmerge = [] impo = 0 for imol in xrange(nmols): MPOmerge.append(MPO[impo]) impo += 1 for iph in xrange(mol[imol].nphs): MPOmerge.append( np.einsum("abcd, defg -> abecfg", MPO[impo], MPO[impo + 1]).reshape(MPO[impo].shape[0], 4, 4, MPO[impo + 1].shape[-1])) impo += 2 self.assertAlmostEqual( \ mpslib.distance(MPO1, MPOmerge), 0.0) energy = MPSsolver.optimization(MPS, MPSdim, MPSQN, MPO, MPOdim, ephtable, pbond, nexciton, procedure, method="2site") self.assertAlmostEqual(np.min(energy) * constant.au2ev, 2.28614053133) energy = MPSsolver.optimization(MPS, MPSdim, MPSQN, MPO, MPOdim, ephtable, pbond, nexciton, procedure, method="1site") self.assertAlmostEqual(np.min(energy) * constant.au2ev, 2.28614053133) MPSnew = MPSsolver.clean_MPS("L", MPS, ephtable, nexciton) self.assertAlmostEqual( \ mpslib.distance(MPSnew, mpslib.conj(MPS)), 0.0) MPSnew = MPSsolver.clean_MPS("R", MPS, ephtable, nexciton) self.assertAlmostEqual( \ mpslib.distance(MPSnew, mpslib.conj(MPS)), 0.0)
def test_construct_MPO(self): Mmax = 10 MPS1, MPSdim1, MPSQN1, MPO1, MPOdim1, MPOQN1, MPOQNidx1, MPOQNtot1, ephtable1, pbond1 = \ MPSsolver.construct_MPS_MPO_2(mol, J, Mmax, nexciton, MPOscheme=1) MPS2, MPSdim2, MPSQN2, MPO2, MPOdim2, MPOQN2, MPOQNidx2, MPOQNtot2, ephtable2, pbond2 = \ MPSsolver.construct_MPS_MPO_2(mol, J, Mmax, nexciton, MPOscheme=2) self.assertEqual(ephtable1, ephtable2) self.assertEqual(pbond1, pbond2) self.assertAlmostEqual( \ mpslib.dot(MPO1, mpslib.conj(MPO1)) + \ mpslib.dot(MPO2, mpslib.conj(MPO2)) - \ mpslib.dot(MPO1, mpslib.conj(MPO2)) - \ mpslib.dot(MPO2, mpslib.conj(MPO1)), 0.0)
def test_construct_MPO_scheme3(self): Mmax = 10 J = np.array([[0.0, -0.1, 0.0], [-0.1, 0.0, -0.3], [0.0, -0.3, 0.0] ]) / constant.au2ev MPS2, MPSdim2, MPSQN2, MPO2, MPOdim2, MPOQN2, MPOQNidx2, MPOQNtot2, ephtable2, pbond2 = \ MPSsolver.construct_MPS_MPO_2(mol, J, Mmax, nexciton, MPOscheme=2) MPS3, MPSdim3, MPSQN3, MPO3, MPOdim3, MPOQN3, MPOQNidx3, MPOQNtot3, ephtable3, pbond3 = \ MPSsolver.construct_MPS_MPO_2(mol, J, Mmax, nexciton, MPOscheme=3) self.assertEqual(ephtable3, ephtable2) self.assertEqual(pbond3, pbond2) self.assertAlmostEqual( \ mpslib.dot(MPO3, mpslib.conj(MPO3)) + \ mpslib.dot(MPO2, mpslib.conj(MPO2)) - \ mpslib.dot(MPO3, mpslib.conj(MPO2)) - \ mpslib.dot(MPO2, mpslib.conj(MPO3)), 0.0)
def hybrid_DMRG_H_SCF(mol, J, nexciton, dmrg_procedure, niterations, DMRGthresh=1e-5, Hthresh=1e-5): ''' The ground state SCF procedure of hybrid DMRG and Hartree(-Fock) approach ''' nmols = len(mol) # initial guess # DMRG part MPS, MPSdim, MPSQN, MPO, MPOdim, MPOQN, MPOQNidx, MPOQNtot, ephtable, pbond = \ MPSsolver.construct_MPS_MPO_2(mol, J, dmrg_procedure[0][0], nexciton) energy = MPSsolver.optimization(MPS, MPSdim, MPSQN, MPO, MPOdim,\ ephtable, pbond, nexciton, dmrg_procedure) # Hartre part WFN = [] for imol in xrange(nmols): for iph in xrange(mol[imol].nphs_hybrid): vw, vv = scipy.linalg.eigh(a=mol[imol].ph_hybrid[iph].H_vib_indep) WFN.append(vv[:, 0]) # loop to optimize both parts for itera in xrange(niterations): print "Loop:", itera MPO, MPOdim, MPOQN, MPOQNidx, MPOQNtot, HAM, Etot = construct_hybrid_Ham( mol, J, MPS, WFN) print "Etot=", Etot MPS_old = mpslib.add(MPS, None) energy = MPSsolver.optimization(MPS, MPSdim, MPSQN, MPO, MPOdim, ephtable, pbond, nexciton, dmrg_procedure) WFN_old = WFN WFN = [] for iham, ham in enumerate(HAM): w, v = scipy.linalg.eigh(a=ham) WFN.append(v[:, 0]) # check convergence angle = np.absolute(mpslib.dot(mpslib.conj(MPS_old), MPS)) res = [scipy.linalg.norm(np.tensordot(WFN[iwfn],WFN[iwfn],axes=0) \ -np.tensordot(WFN_old[iwfn], WFN_old[iwfn], axes=0)) for iwfn in xrange(len(WFN))] if np.all(np.array(res) < Hthresh) and abs(angle - 1.) < DMRGthresh: print "SCF converge!" break # append the coefficient a WFN.append(1.0) return MPS, MPSQN, WFN, Etot
def Exact_Spectra_hybrid_TDDMRG_TDH(spectratype, mol, J, MPS, dipoleMPO, WFN, \ nsteps, dt, E_offset=0.): ''' exact spectra by hybrid TDDMRG/TDH approach for ZT abs and emi ''' assert spectratype in ["emi", "abs"] if spectratype == "emi": space = "GS" else: space = "EX" AketMPS = mpslib.mapply(dipoleMPO, MPS) factor = mpslib.norm(AketMPS) AketMPS = mpslib.scale(AketMPS, 1. / factor) AbraMPS = mpslib.add(AketMPS, None) WFN[-1] *= factor WFNbra = copy.deepcopy(WFN) MPOprop, HAM, Etot = ExactPropagator_hybrid_TDDMRG_TDH(mol, J, AketMPS, WFN, -1.0j * dt, space=space) print "TD Etot", Etot autocorr = [] t = 0. for istep in xrange(nsteps): if istep != 0: t += dt WFN[-1] *= np.exp(-1.0j * Etot * dt) AketMPS = mpslib.mapply(MPOprop, AketMPS) TDH.unitary_propagation(HAM, WFN, dt) ft = mpslib.dot(mpslib.conj(AbraMPS), AketMPS) ft *= np.conj(WFNbra[-1]) * WFN[-1] * np.exp(-1.0j * E_offset * t) for iwfn in xrange(len(WFN) - 1): ft *= np.vdot(WFNbra[iwfn], WFN[iwfn]) autocorr.append(ft) autocorr_store(autocorr, istep) return autocorr
def test_optimization(self, value): MPS, MPSdim, MPSQN, MPO, MPOdim, MPOQN, MPOQNidx, MPOQNtot, ephtable, pbond = \ MPSsolver.construct_MPS_MPO_2(mol, J, procedure[0][0], nexciton, MPOscheme=value[0]) energy = MPSsolver.optimization(MPS, MPSdim, MPSQN, MPO, MPOdim, ephtable, pbond, nexciton, procedure, method="2site") self.assertAlmostEqual(np.min(energy) * constant.au2ev, 2.28614053133) energy = MPSsolver.optimization(MPS, MPSdim, MPSQN, MPO, MPOdim, ephtable, pbond, nexciton, procedure, method="1site") self.assertAlmostEqual(np.min(energy) * constant.au2ev, 2.28614053133) MPSnew = MPSsolver.clean_MPS("L", MPS, ephtable, nexciton) self.assertAlmostEqual( \ mpslib.dot(MPS, mpslib.conj(MPS)) + \ mpslib.dot(MPSnew, mpslib.conj(MPSnew)) - \ mpslib.dot(MPS, mpslib.conj(MPSnew)) - \ mpslib.dot(MPSnew, mpslib.conj(MPS)), 0.0) MPSnew = MPSsolver.clean_MPS("R", MPS, ephtable, nexciton) self.assertAlmostEqual( \ mpslib.dot(MPS, mpslib.conj(MPS)) + \ mpslib.dot(MPSnew, mpslib.conj(MPSnew)) - \ mpslib.dot(MPS, mpslib.conj(MPSnew)) - \ mpslib.dot(MPSnew, mpslib.conj(MPS)), 0.0)
def ZeroTcorr_hybrid_TDDMRG_TDH(mol, J, iMPS, dipoleMPO, WFN0, nsteps, dt, ephtable,\ thresh=0., TDDMRG_prop_method="C_RK4", E_offset=0., cleanexciton=None, QNargs=None): ''' ZT linear spectra ''' AketMPS = mpslib.mapply(dipoleMPO, iMPS, QNargs=QNargs) factor = mpslib.norm(AketMPS, QNargs=QNargs) AketMPS = mpslib.scale(AketMPS, 1. / factor, QNargs=QNargs) AbraMPS = mpslib.add(AketMPS, None, QNargs=QNargs) WFN0[-1] *= factor WFNket = copy.deepcopy(WFN0) WFNbra = copy.deepcopy(WFN0) autocorr = [] t = 0.0 for istep in xrange(nsteps): if istep != 0: t += dt if istep % 2 == 1: AketMPS, WFNket = hybrid_TDDMRG_TDH(mol, J, AketMPS, WFNket,\ dt, ephtable, thresh=thresh, cleanexciton=cleanexciton, QNargs=QNargs, \ TDDMRG_prop_method=TDDMRG_prop_method, TDH_prop_method="unitary") else: AbraMPS, WFNbra = hybrid_TDDMRG_TDH(mol, J, AbraMPS, WFNbra,\ -dt, ephtable, thresh=thresh, cleanexciton=cleanexciton, QNargs=QNargs, \ TDDMRG_prop_method=TDDMRG_prop_method, TDH_prop_method="unitary") ft = mpslib.dot(mpslib.conj(AbraMPS, QNargs=QNargs), AketMPS, QNargs=QNargs) ft *= np.conj(WFNbra[-1]) * WFNket[-1] * np.exp(-1.0j * E_offset * t) for iwfn in xrange(len(WFN0) - 1): ft *= np.vdot(WFNbra[iwfn], WFNket[iwfn]) autocorr.append(ft) autocorr_store(autocorr, istep) return autocorr
def FiniteT_spectra_TDDMRG_TDH(spectratype, T, mol, J, nsteps, dt, insteps, pbond, ephtable,\ thresh=0., ithresh=1e-4, TDDMRG_prop_method="C_RK4", E_offset=0., QNargs=None): ''' FT linear spectra ''' assert spectratype in ["abs", "emi"] dipoleMPO, dipoleMPOdim = MPSsolver.construct_onsiteMPO(mol, pbond, "a^\dagger", dipole=True, QNargs=QNargs) # construct initial thermal equilibrium density matrix and apply dipole matrix if spectratype == "abs": nexciton = 0 DMMPO, DMH = FT_DM_hybrid_TDDMRG_TDH(mol, J, nexciton, T, insteps, pbond, ephtable, \ thresh=ithresh, TDDMRG_prop_method=TDDMRG_prop_method, QNargs=QNargs, space="GS") DMMPOket = mpslib.mapply(dipoleMPO, DMMPO, QNargs=QNargs) else: nexciton = 1 DMMPO, DMH = FT_DM_hybrid_TDDMRG_TDH(mol, J, nexciton, T, insteps, pbond, ephtable, \ thresh=ithresh, TDDMRG_prop_method=TDDMRG_prop_method, QNargs=QNargs, space=None) if QNargs is not None: dipoleMPO[1] = [[0] * len(impsdim) for impsdim in dipoleMPO[1]] dipoleMPO[3] = 0 DMMPOket = mpslib.mapply(DMMPO, dipoleMPO, QNargs=QNargs) factor = mpslib.norm(DMMPOket, QNargs=QNargs) DMMPOket = mpslib.scale(DMMPOket, 1. / factor, QNargs=QNargs) DMMPObra = mpslib.add(DMMPOket, None, QNargs=QNargs) DMH[-1] *= factor DMHket = copy.deepcopy(DMH) DMHbra = copy.deepcopy(DMH) autocorr = [] t = 0.0 def prop(DMMPO, DMH, dt): MPOprop, HAM, Etot = ExactPropagator_hybrid_TDDMRG_TDH(mol, J, \ DMMPO, DMH, -1.0j*dt, space="GS", QNargs=QNargs) DMMPO = mpslib.mapply(DMMPO, MPOprop, QNargs=QNargs) DMH[-1] *= np.exp(-1.0j * Etot * dt) for iham, hamprop in enumerate(HAM): w, v = scipy.linalg.eigh(hamprop) DMH[iham] = DMH[iham].dot(v).dot(np.diag(np.exp(-1.0j * dt * w))).dot(v.T) DMMPO, DMH = hybrid_TDDMRG_TDH(mol, J, DMMPO, DMH, \ -dt, ephtable, thresh=thresh, QNargs=QNargs, TDDMRG_prop_method=TDDMRG_prop_method, normalize=1.0) return DMMPO, DMH print("Real time dynamics starts!") for istep in xrange(nsteps): print("istep=", istep) if istep != 0: t += dt if istep % 2 == 0: DMMPObra, DMHbra = prop(DMMPObra, DMHbra, dt) else: DMMPOket, DMHket = prop(DMMPOket, DMHket, -dt) ft = mpslib.dot(mpslib.conj(DMMPObra, QNargs=QNargs), DMMPOket, QNargs=QNargs) ft *= np.conj(DMHbra[-1]) * DMHket[-1] for idm in xrange(len(DMH) - 1): ft *= np.vdot(DMHbra[idm], DMHket[idm]) if spectratype == "emi": ft = np.conj(ft) # for emi bra and ket is conjugated ft *= np.exp(-1.0j * E_offset * t) autocorr.append(ft) autocorr_store(autocorr, istep) return autocorr