Beispiel #1
0
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
Beispiel #2
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
Beispiel #3
0
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
Beispiel #4
0
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