def initMPS(dmrg, debug=False): if dmrg.comm.rank == 0: print '[mpo_dmrg_util.initMPS]' # Product state MPS0 if dmrg.occun is None: mps0 = mps0mixed(dmrg.dphys) ifsym = False else: qnuml, qnumr, mps0 = mps0occun(dmrg.dphys, dmrg.occun, dmrg.isym) dmrg.qnuml = copy.deepcopy(qnuml) dmrg.qnumr = copy.deepcopy(qnumr) ifsym = True # DUMP fmps0 = h5py.File(dmrg.path + '/mps0', 'w') mpo_dmrg_io.dumpMPS(fmps0, mps0, icase=0) if debug: dmrg.checkMPS(fmps0) # init operators from mps fnamel = dmrg.path + '/lop' fnamer = dmrg.path + '/rop' mpo_dmrg_init.genBops(dmrg, fnamel, dmrg.nops, -1, ifslc=False) mpo_dmrg_init.genHops(dmrg, fmps0, fmps0, fnamer, 'R') # Initialize MPS sitelst = range(dmrg.nsite) if debug: mpo_dmrg_init.genHops(dmrg, fmps0, fmps0, fnamel, 'L') mpo_dmrg_opt.sweep(dmrg, sitelst, dmrg.initNcsite, 'R', ifsym=ifsym) # Initialization mpo_dmrg_opt.sweep(dmrg, sitelst, dmrg.initNcsite, 'L', ifsym=ifsym) # Nosym sweeps for isweep in range(dmrg.initNsweep): mpo_dmrg_opt.sweep(dmrg, sitelst, dmrg.initNcsite, 'R', ifsym=ifsym) mpo_dmrg_opt.sweep(dmrg, sitelst, dmrg.initNcsite, 'L', ifsym=ifsym) fmps0.close() return 0
def checkMPS(self,fbra=None,fket=None,status='L',fname0='top',ifep=False): rank = self.comm.rank if rank == 0: print '\n[mpo_dmrg_class.checkMPS] size=',self.comm.size assert self.isym in [1,2] # Must have symmetry. assert not isinstance(fbra,basestring) assert not isinstance(fket,basestring) # Setup files if fbra is not None: fbmps = fbra else: if status == 'L': fbmps = h5py.File(self.path+'/lmps','r') elif status == 'R': fbmps = h5py.File(self.path+'/rmps','r') if fket is not None: fkmps = fket else: fkmps = fbmps # bond dimension nsite = fbmps['nsite'].value bdim = map(lambda x:len(x),mpo_dmrg_io.loadQnums(fbmps)) kdim = map(lambda x:len(x),mpo_dmrg_io.loadQnums(fkmps)) # Quantities to be checked energy = None ovlp = None psum = None fnameh = self.path+'/'+fname0+'_hop' fnames = self.path+'/'+fname0+'_sop' fnamep = self.path+'/'+fname0+'_pop' # Energy exphop = mpo_dmrg_init.genHops(self,fbmps,fkmps,fnameh,status) hpwts = self.fhop['wts'].value esum = numpy.dot(hpwts,exphop) esum = self.comm.reduce(esum,op=MPI.SUM,root=0) # S if rank == 0: ovlp = mpo_dmrg_init.genSops(self,fbmps,fkmps,fnames,status) # P if rank == 0 and self.ifs2proj: exppop = mpo_dmrg_init.genPops(self,fbmps,fkmps,fnamep,status) psum = numpy.dot(self.qwts,exppop) # Final print if rank == 0: if psum is not None: energy = esum/psum else: energy = esum/ovlp print print 'Summary for '+status+'-MPS:' print ' npts =',self.npts print ' <H(P)> =',esum print ' ovlp =',ovlp print ' <(P)> =',psum print ' Energy =',energy print ' Econst =',self.const print ' Etotal =',energy+self.const print ' bBdims =',bdim print ' kBdims =',kdim # Check Ecomponents if ifep: if self.ifs2proj: npts = self.npts else: npts = 1 ecomp = self.comm.gather(exphop,root=0) opswt = self.comm.gather(hpwts,root=0) if rank == 0: ecomp = numpy.array(ecomp).flatten() opswt = numpy.array(opswt).flatten() ecomp = ecomp*opswt # Sum over grid points tmp = numpy.zeros(self.sbas) for ipt in range(npts): tmp += ecomp[ipt::npts] # Spatial orbitals ecomp = numpy.zeros(self.nsite) # Sum over spin cases for ispin in range(2): ecomp += tmp[ispin::2] print '### Energy decompositions: <Hp> ###' print ' nsite =',self.nsite print ' ecomp =',ecomp if psum is not None: self.ecomp = ecomp/psum else: self.ecomp = ecomp/ovlp print ' ecomp =',self.ecomp print ' etot =',numpy.sum(ecomp) return energy,esum,ovlp,psum
def vpt(dmrg): rank = dmrg.comm.rank # 1. LHS: Prepare operators for H0 dmrg.fdopXfhop() hmat, smat = genCIHamiltonian(dmrg) dmrg.fdopXfhop() # 2. E0 = <Psi0|H|Psi0> dmrg.nref = len(dmrg.wfex) fbra = dmrg.wfex[0] energy, esum, ovlp, psum = dmrg.checkMPS(fbra, fbra, ifprt=False) # Normalization constant if rank == 0: dmrg.e0 = hmat[0, 0] / smat[0, 0] dmrg.e1 = energy - dmrg.e0 dmrg.et = energy - dmrg.emix * dmrg.e1 dmrg.n0 = 1.0 / math.sqrt(smat[0, 0]) # 3. RHS = <0|H|psi1> v01 = numpy.zeros(dmrg.nref) for iref in range(1, dmrg.nref): print '\n ### Hams: iref =', iref, ' rank= ', rank, '###' fket = dmrg.wfex[iref] # <A|H|B> fnamel = dmrg.path + '/ref' + str(iref) + '_lhop' fnamer = dmrg.path + '/ref' + str(iref) + '_rhop' mpo_dmrg_init.genBops(dmrg, fnamer, dmrg.nops, dmrg.nsite, ifslc=True) exphop = mpo_dmrg_init.genHops(dmrg, fbra, fket, fnamel, 'L') hpwts = dmrg.fhop['wts'].value esum = numpy.dot(hpwts, exphop) esum = dmrg.comm.reduce(esum, op=MPI.SUM, root=0) if rank == 0: v01[iref] = dmrg.n0 * esum.real # 4. Solve <Psi1|H0E0|Psi1> = -<Psi1|V|Psi0> if rank == 0: ndim = hmat.shape[0] Amat = (hmat - dmrg.et * smat)[numpy.ix_(range(1, ndim), range(1, ndim))] bvec = v01[1:] cvec = scipy.linalg.solve(Amat, -bvec) e2o = cvec.dot(bvec) e2s = numpy.sum(bvec) lhs = numpy.sum(Amat) e2v = lhs + 2.0 * e2s # L = <Psi1|H0-E0|Psi1>+2<Psi1|V|0> print print '=' * 40 print 'Summary of PT results: ifH0 =', dmrg.ifH0 print '=' * 40 print ' h0mat = \n', hmat print ' smat = \n', smat print ' emix =', dmrg.emix print ' e0 = ', dmrg.e0 print ' e1 = ', dmrg.e1 print ' eH = ', energy print ' et = ', dmrg.et print ' n0 = ', dmrg.n0 print ' ndim =', ndim - 1 print ' Amat = \n', Amat print ' bvec = \n', bvec print ' (1) e2[ Sum of RHS ] =', e2s print ' (2) e2[ Functional ] =', e2v print ' * difference =', e2v - e2s print ' * <Psi1|H0-E0|Psi1> =', lhs print ' (3) e2[ ROptimized ] =', e2o print ' * difference =', e2o - e2s print ' * cvec =', cvec e2 = e2o #========================================== # If the difference is large, then this # indicate in the solution of psi1, the # accuracy [D1] is not sufficiently high. #========================================== else: e2 = None cvec = None return e2, cvec
def initOps(dmrg, fmps): rank = dmrg.comm.rank if rank == 0: print '\n[mpo_dmrg_util.initOps]' #-------------------------------------------------------- # Initialization-0: normal initialization (lrop) # H0 or H for LHS of eigenvalue or linear equations [PT] #-------------------------------------------------------- if dmrg.ifpt and dmrg.ifH0: dmrg.fdopXfhop() fnamel = dmrg.path + '/lop' fnamer = dmrg.path + '/rop' mpo_dmrg_init.genBops(dmrg, fnamer, dmrg.nops, dmrg.nsite, ifslc=True) mpo_dmrg_init.genHops(dmrg, fmps, fmps, fnamel, 'L') if dmrg.ifpt and dmrg.ifH0: dmrg.fdopXfhop() #-------------------------------------------------------- # Initialization-0: normal initialization (lrpop) # Renormalized operators for <L|P|L>. #-------------------------------------------------------- if rank == 0 and dmrg.ifs2proj: fnamelp = dmrg.path + '/lpop' fnamerp = dmrg.path + '/rpop' mpo_dmrg_init.genBops(dmrg, fnamerp, dmrg.npts, dmrg.nsite, ifslc=False) mpo_dmrg_init.genPops(dmrg, fmps, fmps, fnamelp, 'L') #-------------------------------------------------------- if dmrg.ifpt: dmrg.ifex = True dmrg.nref = len(dmrg.wfex) # 2016.09.13: By default, all MPS in wfex is in left canonical form! if len(dmrg.wfex_canon) == 0: dmrg.wfex_canon = [True] * dmrg.nref fbra = fmps #-------------------------------------------------------- # Initialization-1: initialization (lrsop/lrpop) # Excited states: Only rank-0 compute overlaps #-------------------------------------------------------- if rank == 0 and dmrg.ifex: for iref in range(dmrg.nref): print '\n ### Ovlps: iref =', iref, ' rank =', rank, '###' fket = dmrg.wfex[iref] # <A|B> if not dmrg.ifs2proj: fnamel = dmrg.path + '/ref' + str(iref) + '_lsop' fnamer = dmrg.path + '/ref' + str(iref) + '_rsop' mpo_dmrg_init.genBmat(dmrg, fnamer, dmrg.nsite) mpo_dmrg_init.genSops(dmrg, fbra, fket, fnamel, 'L') # <A|P|B> else: fnamelp = dmrg.path + '/ref' + str(iref) + '_lpop' fnamerp = dmrg.path + '/ref' + str(iref) + '_rpop' mpo_dmrg_init.genBops(dmrg, fnamerp, dmrg.npts, dmrg.nsite, ifslc=False) mpo_dmrg_init.genPops(dmrg, fbra, fket, fnamelp, 'L') #-------------------------------------------------------- # RHS of PT equation: <fmps|H|MPS[i]> if dmrg.ifpt: # Generate E0 initE0pt(dmrg, fmps) #-------------------------------------------------------- # Initialization-2: initialization (lrhop) # Blocks for <Psi|H|Psi[i]> #-------------------------------------------------------- ln = '#' * 10 for iref in range(dmrg.nref): print '\n' + ln + ' <Psi|H|Psi[i]>: iref =', iref, ' rank=', rank, ln fket = dmrg.wfex[iref] # <A|H|B> fnamel = dmrg.path + '/ref' + str(iref) + '_lhop' fnamer = dmrg.path + '/ref' + str(iref) + '_rhop' mpo_dmrg_init.genBops(dmrg, fnamer, dmrg.nops, dmrg.nsite, ifslc=True) mpo_dmrg_init.genHops(dmrg, fbra, fket, fnamel, 'L') #-------------------------------------------------------- # Initialization-3: initialization (lrdop) # Blocks for <Psi|H0|Psi[i]> #-------------------------------------------------------- if dmrg.ifH0: dmrg.fdopXfhop() for iref in range(dmrg.nref): print '\n' + ln + ' <Psi|H0|Psi[i]>: iref =', iref, ' rank=', rank, ln fket = dmrg.wfex[iref] # <A|H|B> fnamel = dmrg.path + '/ref' + str(iref) + '_ldop' fnamer = dmrg.path + '/ref' + str(iref) + '_rdop' mpo_dmrg_init.genBops(dmrg, fnamer, dmrg.nops, dmrg.nsite, ifslc=True) mpo_dmrg_init.genHops(dmrg, fbra, fket, fnamel, 'L') dmrg.fdopXfhop() #-------------------------------------------------------- return 0