Beispiel #1
0
def sweep_updateBoundary(dmrg, ncsite, sitelst, qred, srotR, status):
    if ncsite == 2:
        if status == 'L' and sitelst[-1] == dmrg.nsite - 1:
            # >>> Only the gs state is saved for generating MPS.
            smat = srotR[0]
            norm = numpy.linalg.norm(smat)
            if (not dmrg.ifpt) or (dmrg.ifpt and dmrg.ifcompression):
                smat = smat / norm
            key = mpo_dmrg_dotutil.floatKey(dmrg.qsectors.keys()[0])
            qsym = [numpy.array(eval(key))]
            if dmrg.ifQt:
                qtmp = qtensor.qtensor([False, False, True])
                qtmp.fromDenseTensor(smat,
                                     [qred, dmrg.qphys[dmrg.nsite - 1], qsym])
                smat = qtmp
            # DUMP
            mpo_dmrg_io.saveQnum(dmrg.flmps, dmrg.nsite, qsym)
            mpo_dmrg_io.saveSite(dmrg.flmps, dmrg.nsite - 1, smat)
        elif status == 'R' and sitelst[0] == 0:
            # >>> Only the gs state is saved for generating MPS.
            smat = srotR[0]
            norm = numpy.linalg.norm(smat)
            if (not dmrg.ifpt) or (dmrg.ifpt and dmrg.ifcompression):
                smat = smat / norm
            key = mpo_dmrg_dotutil.floatKey(dmrg.qsectors.keys()[0])
            qsym = [numpy.array(eval(key))]
            if dmrg.ifQt:
                qtmp = qtensor.qtensor([True, False, False])
                qtmp.fromDenseTensor(smat, [qsym, dmrg.qphys[0], qred])
                smat = qtmp

# DUMP
            mpo_dmrg_io.saveQnum(dmrg.frmps, 0, qsym)
            mpo_dmrg_io.saveSite(dmrg.frmps, 0, smat)
    return 0
Beispiel #2
0
def sweep_updateSite(dmrg, isite, ncsite, sigs, qred, site, status):
    # Update symmetry and save sites
    if status == 'L':
        # Example:[==**-] isite=2, lmps[2], qnuml[3]
        dmrg.sigsl[isite + 1] = sigs.copy()
        dmrg.qnuml[isite + 1] = qred.copy()
        if dmrg.ifQt:
            qtmp = qtensor.qtensor([False, False, True])
            #				Ql[i-1]  +  Qn[i]  =  Ql[i]
            qtmp.fromDenseTensor(site, [dmrg.qlst[0], dmrg.qlst[1], qred])
            siteN = qtmp
        else:
            siteN = site.copy()
        # DUMP
        mpo_dmrg_io.saveQnum(dmrg.flmps, isite + 1, qred)
        mpo_dmrg_io.saveSite(dmrg.flmps, isite, siteN)
    elif status == 'R':
        # Example: [--**=] isite=2, jsite=3, rmps[3], qnumr[3]
        jsite = isite + ncsite - 1
        dmrg.sigsr[jsite] = sigs.copy()
        dmrg.qnumr[jsite] = qred.copy()
        if dmrg.ifQt:
            qtmp = qtensor.qtensor([True, False, False])
            #		          Qr[i-1]  =  Qn[i]   +   Qr[i]
            qtmp.fromDenseTensor(site, [qred, dmrg.qlst[-2], dmrg.qlst[-1]])
            siteN = qtmp
        else:
            siteN = site.copy()
        # DUMP
        mpo_dmrg_io.saveQnum(dmrg.frmps, jsite, qred)
        mpo_dmrg_io.saveSite(dmrg.frmps, jsite, siteN)
    return siteN
Beispiel #3
0
   def default(self,sc,fmps=None):
      rank = self.comm.rank
      self.schedule = sc
      self.crit_tol = sc.tol
      if rank == 0: 
	 print '\n[mpo_dmrg_class.default]'
	 mpo_dmrg_prt.title(self)
      ti = time.time()
      # Count states
      self.initStates()
      if rank == 0: 
	 # Only set Dcut for rank-0 is sufficient, 
	 # as RDM truncation is done here.
	 if self.Dcut is not None:
	    print ' Dcut = ',self.Dcut
	    # Similar to qnuml and qnumr
	    assert len(self.Dcut) == self.nsite-1
	    self.Dcut = [1]+self.Dcut+[1]
         # LogFile in current directory
	 flog_name = 'log_'+os.path.split(self.path)[-1]
	 print ' flog_name =',flog_name
	 flog = open(flog_name,'w')
         flog.write('path:'+self.path+'\n')
      # MPSfile
      self.flmps = h5py.File(self.path+'/lmps','w')
      self.frmps = h5py.File(self.path+'/rmps','w')
      self.flmps['nsite'] = self.nsite
      self.frmps['nsite'] = self.nsite
      mpo_dmrg_io.saveQnum(self.flmps,0,self.qnuml[0])
      mpo_dmrg_io.saveQnum(self.frmps,self.nsite,self.qnumr[-1])
      # Initialize L-MPS by a single left sweep
      if fmps is None:
	 # This is not allowed for using Qt.
	 assert self.ifQt == False 
	 self.status = 'init'
         self.Dmax   = self.schedule.MaxMs[0]  
         self.crit_e = self.schedule.Tols[0]   
         self.noise  = self.schedule.Noises[0]
         mpo_dmrg_util.initMPS(self)
      # Use L-MPS from input
      else:
         self.comm.Barrier()
	 # Not only requires qnuml for setting up mpo_dmrg_util
	 self.qnuml = mpo_dmrg_io.loadQnums(fmps)
	 # but also the sites are needed to be copied to flmps!
	 mpo_dmrg_io.copyMPS(self.flmps,fmps,self.ifQt)
         self.comm.Barrier()
	 # Initialize operators
	 mpo_dmrg_util.initOps(self,fmps)	 
      # Optimize
      self.comm.Barrier()
      self.esweeps = []	
      self.psi0 = None
      self.eav = []
      self.dwt = []
      sitelst  = range(self.nsite)
      ifconv = False
      deltaE = 1.e3
      eold   = 1.e3
      isweep = -1
      # Optimize following the schedule
      for isweep in range(self.schedule.maxiter):
	 if rank == 0: print '\n'+'#'*30+' isweep = ',isweep,'#'*30
	 t0 = time.time()
	 # Record status
	 self.isweep = isweep
	 # Setup parameters
	 self.schedule.getParameters(self,isweep)
	 # Optimization
	 result1 = mpo_dmrg_opt.sweep(self,sitelst,self.ncsite,'R',ifsym=self.ifsym)
	 result2 = mpo_dmrg_opt.sweep(self,sitelst,self.ncsite,'L',ifsym=self.ifsym)
	 nmvp1,indx1,eav1,dwt1,elst1,dlst1 = result1
	 nmvp2,indx2,eav2,dwt2,elst2,dlst2 = result2
	 if rank == 0: mpo_dmrg_prt.flogWrite(self,flog,isweep,result1,result2) 	 
	 self.nmvp.append(nmvp1+nmvp2)
	 self.esweeps += elst1+elst2
	 if eav1 < eav2:
    	    self.eav.append(eav1)
    	    self.dwt.append(dwt1)
	    eav = eav1
	 else:
    	    self.eav.append(eav2)
    	    self.dwt.append(dwt2)
	    eav = eav2
         # Check convergence
	 t1 = time.time()
	 self.Energy = eav
    	 deltaE = eav-eold
	 if rank == 0: print 'Summary: isweep=',isweep,' Emin=',eav,\
			     ' dE=%9.2e  tol=%8.1e  t=%8.1e s'%(deltaE,self.crit_tol,t1-t0)
	 # Check convergence
	 ifconv = self.schedule.checkConv(self,isweep,deltaE)
         eold = eav
	 if ifconv: break
      # Save	 
      self.ifconv = ifconv
      self.nsweep = isweep + 1
      self.deltaE = deltaE
      tf = time.time()
      self.comm.Barrier()
      # Adjust a little bit to allow isweep = 0.
      # The only problem is the R-MPS is not initialized.
      if rank == 0 and isweep != -1: mpo_dmrg_prt.finalSweep(self,tf-ti)
      if rank == 0: flog.close()
      self.comm.Barrier()
      return 0