コード例 #1
0
def init_first_site(model: BaseModel, nrg_maxkeep: int,
                    meass: List[Tuple[str, int]]):
    '''初始化第一个site\n
    这个时候只有1和N上面的block,创建这两个block上面的升降算符\n
    还有以后观测要用的算符。
    meass中应该是[(1, 'sz'), (N, 'sz')](N是最后一个格子的编号)\n
    这样的内容
    '''
    conf = DMRGConfig(model, nrg_maxkeep)
    #
    left = first_leftblock(model.sites[0])
    #创建第一个格子上的哈密顿量,还有第一个格子的产生算符
    hamleft = create_hamiltonian_of_site(left.fock_basis, model.coef_u,
                                         model.get_coef_mu(model.sites[0]))
    cup1 = create_operator_of_site(left.fock_basis,
                                   OperFactory.create_spinup())
    cdn1 = create_operator_of_site(left.fock_basis,
                                   OperFactory.create_spindown())
    #把现在的结果暂存到dconf
    conf.left_tmp_reset(model.sites[0], left, hamleft)
    conf.left_tmp_add_oper(cup1)
    conf.left_tmp_add_oper(cdn1)
    #
    right = first_rightblock(model.sites[-1])
    #创建最后一个格子上的哈密顿量,还有最后一个格子的产生算符
    hamright = create_hamiltonian_of_site(right.fock_basis, model.coef_u,
                                          model.get_coef_mu(model.sites[-1]))
    cuplast = create_operator_of_site(right.fock_basis,
                                      OperFactory.create_spinup())
    cdnlast = create_operator_of_site(right.fock_basis,
                                      OperFactory.create_spindown())
    #把右侧的结果也暂存到dconf
    conf.right_tmp_reset(model.sites[-1], right, hamright)
    conf.right_tmp_add_oper(cuplast)
    conf.right_tmp_add_oper(cdnlast)
    #把block上面的算符存储到tmp里,以后需要的是ext上面的算符
    leftstor = conf.get_leftblock_storage(model.sites[0])
    rightstor = conf.get_rightblock_storage(model.sites[-1])
    for prefix, idx in meass:
        if idx == model.sites[0]:
            stor = leftstor
            basis = left
        elif idx == model.sites[-1]:
            stor = rightstor
            basis = right
        else:
            raise ValueError('这个算符不在第一个或最后一个格子')
        measop = create_operator_of_site(basis.fock_basis,
                                         OperFactory.create_by_name(prefix))
        stor.storage_meas(prefix, measop)
    return conf
コード例 #2
0
ファイル: nrg_iter.py プロジェクト: arque2015/mypydmrg
def leftblock_to_next(
        conf: DMRGConfig,
        phi_idx: int,
        newbonds: List[int],
        extoper_storage: List[int],
        tmpoper_storage: List[int],
        measuer_storage: List[Tuple[str, int]]
    ):
    '''将leftblock向前推进一个格子\n
    left是需要推进的block\n
    phi_idx是新的left的idx,这个和block_len不一定是一个东西\n
    conf是程序运行时的句柄\n
    newbonds是新加的这个site和哪些site有bond(新的site是left.fock_basis.site[-1]+1)\n
    extoper_storage是指|phi^phi_idx-1, s^phi_idx>这个基上有哪些算符需要保存\n
    村下来的extoper以后要用到superblock上。\n
    tmpoper_storage是指在|phi^phi_idx>这个基上要临时存储的算符,用在下一次递推\n
    时的哈密顿量计算,以及下一次的迭代中需要保存的ext\n
    measure_storage是指以后dmrg需要观测的过程中要计算的算符,需要保存到leftstorage中\n
    leftext[phi_idx-1]上面的观测算符也需要保存,由于leftext[phi_idx-1]和\n
    leftblock[phi_idx]实际上是一个block_len这里用一个参数指定就可以了\n
    '''
    leftstorage = conf.get_leftblock_storage(phi_idx-1)
    left = leftstorage.block
    hamleft = leftstorage.hamiltonian
    ### 开始处理leftext在leftext上面工作的内容
    #把left扩展一个格子
    leftext = extend_leftblock(left)
    #给leftext进行初始化,leftext[phi_idx-1]中存的就是leftblock[phi_idx-1]的extend
    conf.leftext_reset(phi_idx-1, leftext)
    #把哈密顿量扩展一个格子
    hamleft = extend_leftblock_hamiltonian(hamleft, leftext)
    #把扩展基上的哈密顿量存下来
    conf.storage_leftext_ham(phi_idx-1, hamleft)
    #存储需要进行扩展的算符
    maintain_opers = {}
    #创建新的格子上厄的两个算符并且扩展
    newup = create_operator_of_site(leftext.stbss, OperFactory.create_spinup())
    newup = leftsite_extend_oper(leftext, newup)
    newdown = create_operator_of_site(leftext.stbss, OperFactory.create_spindown())
    newdown = leftsite_extend_oper(leftext, newdown)
    #if leftext.stbss.sites[0] in tmpoper_storage:
    maintain_opers[leftext.stbss.sites[0]] = (newup, newdown)
    #把left_tmp中所有的算符扩展
    #注意这个时候leftstorage.oper_storage_list会被修改,
    #不能在这个上面进行循环
    while len(leftstorage.oper_storage_list) > 0:
    #for stidx in leftstorage.oper_storage_list:
        stidx = leftstorage.oper_storage_list[0]
        #把left上面的两个算符弹出
        stup, stdown = leftstorage.pop_oper(stidx)
        #将两个算符扩展
        stup = leftblock_extend_oper(leftext, stup)
        stdown = leftblock_extend_oper(leftext, stdown)
        maintain_opers[stidx] = (stup, stdown)
    #把需要保存到leftext中的算符保存下来
    for stidx in extoper_storage:
        conf.storage_leftext_oper(phi_idx-1, maintain_opers[stidx][0])
        conf.storage_leftext_oper(phi_idx-1, maintain_opers[stidx][1])
    #找到构成bond的算符,把新的hopping添加到哈密顿量
    for bstidx in newbonds:
        coef_t = conf.model.get_t_coef(bstidx, newup.siteidx)
        #自旋上部分
        tar_up = maintain_opers[bstidx][0]
        hamleft.add_hopping_term(newup, tar_up, coef_t)
        #自旋下部分
        tar_down = maintain_opers[bstidx][1]
        hamleft.add_hopping_term(newdown, tar_down, coef_t)
    #构建U项并扩展,然后添加到哈密顿量
    newiu = create_operator_of_site(leftext.stbss, OperFactory.create_u())
    newiu = leftsite_extend_oper(leftext, newiu)
    hamleft.add_u_term(newiu, conf.model.coef_u)
    #构建Mu项并扩展,然后添加到哈密顿量
    coef_mu = conf.model.get_coef_mu(phi_idx)
    if coef_mu != 0:
        newnu = create_operator_of_site(leftext.stbss, OperFactory.create_numup())
        newnu = leftsite_extend_oper(leftext, newnu)
        hamleft.add_mu_term(newnu, coef_mu)
        newnd = create_operator_of_site(leftext.stbss, OperFactory.create_numdown())
        newnd = leftsite_extend_oper(leftext, newnd)
        hamleft.add_mu_term(newnd, coef_mu)
    ### 开始从leftext升级到下一个left
    #调用get_phival_from_hamleft,得到能量本正值
    #获得相应的自旋sector限制
    if phi_idx <= numpy.floor_divide(conf.model.size, 2):
        sector = None
    else:
        sector = []
        sp1min = conf.spin_sector[0] - (conf.model.size - phi_idx)
        if sp1min < 0:
            sp1min = 0
        sp1max = conf.spin_sector[0]
        sp2min = conf.spin_sector[1] - (conf.model.size - phi_idx)
        if sp2min < 0:
            sp2min = 0
        sp2max = conf.spin_sector[1]
        for se1 in range(sp1min, sp1max + 1):
            for se2 in range(sp2min, sp2max + 1):
                sector.append((se1, se2))
    phival = get_phival_from_hamleft(
        hamleft,
        leftext,
        conf.nrg_max_keep,
        restrict_sector=sector
    )
    #给leftext升级成新的基,这个时候phival其实没什么用
    #但fermionic在DEBUG_MODE下会解出basis在fock_basis下的系数,这个是需要的
    newleft = update_to_leftblock(leftext, phival)
    #给哈密顿量进行更新
    hamleft = update_leftblockextend_hamiltonian(newleft, hamleft, phival)
    #把tmp中保存的leftblock[phi_idx-1]的观测算符取出来,并扩展到
    #leftext[phi_idx-1]
    ext_measops = {}
    for meas in measuer_storage:
        if meas[1] == phi_idx:#如果是这次新加的格子,就创建一个而不是读取
            meaop = create_operator_of_site(
                leftext.stbss,
                OperFactory.create_by_name(meas[0])
            )
            meaop = leftsite_extend_oper(leftext, meaop)
        else:
            meaop = leftstorage.get_meas(meas[0], meas[1])
            meaop = leftblock_extend_oper(leftext, meaop)
        ext_measops['%s,%d' % meas] = meaop
    #给conf中的left_tmp重置,现在left_tmp应该保存phi_idx的哈密顿量和算符了
    conf.left_tmp_reset(phi_idx, newleft, hamleft)
    #给下一次运算需要保存的算符更新
    for stidx in tmpoper_storage:
        up_ext, down_ext = maintain_opers[stidx]
        up_upd = update_leftblockextend_oper(newleft, up_ext, phival)
        down_upd = update_leftblockextend_oper(newleft, down_ext, phival)
        conf.left_tmp_add_oper(up_upd)
        conf.left_tmp_add_oper(down_upd)
    #给以后需要观测的算符进行保存
    leftext_stor = conf.get_leftext_storage(phi_idx-1)
    leftstorage = conf.get_leftblock_storage(phi_idx)
    for prefix, stidx in measuer_storage:
        #如果这个site是之前的block上面的,已经扩展到了leftext[phi_idx-1]
        #保存到leftext[phi_idx-1]
        #升级到leftblock[phi_idx],存到left_tmp
        meaop = ext_measops['%s,%d' % (prefix, stidx)]
        leftext_stor.storage_meas(prefix, meaop)
        #升级
        meaop = update_leftblockextend_oper(newleft, meaop, phival)
        leftstorage.storage_meas(prefix, meaop)
    return newleft
コード例 #3
0
def leftblockextend_to_next(conf: DMRGConfig, phi_idx: int,
                            extrabonds: List[int], newbonds: List[int],
                            extoper_storage: List[int],
                            measure_storage: List[Tuple[str, int]],
                            spin_sector, maxkeep: int):
    '''在右侧的rightext迭代到位以后,开始左侧的迭代\n
    这个时候的phi_idx是新的leftblockext的idx,新加的site就是phi_idx+1,\n
    相对应的rightblockext的idx就是phi_idx+2
    '''
    leftstorage = conf.get_leftext_storage(phi_idx - 1)
    rightstorage = conf.get_rightext_storage(phi_idx + 2)
    #首先要把superblock拼出来
    sector_idxs, mat, superext = get_superblock_ham(conf.model, leftstorage,
                                                    rightstorage, spin_sector,
                                                    extrabonds)
    #把基态解出来
    eigvals, eigvecs = scipy.sparse.linalg.eigsh(mat, k=1, which='SA')
    #numpy.linalg.eigh(mat)
    ground = eigvecs[:, 0]
    ground_erg = eigvals[0]
    #把基态的信息保留下来
    conf.ground_vec = ground
    conf.ground_secidx = sector_idxs
    conf.ground_superext = superext
    #构造密度矩阵
    lidxs, ridxs, mat = get_density_root(  #pylint: disable=unused-variable
        leftstorage, rightstorage, sector_idxs, ground)
    #这个mat行是phi^phi_idx-1,s^phi_idx,列是s^phi_idx+1,phi^phi_idx+2
    #lidxs是mat上的行到leftext的基的指标
    #利用矩阵乘法收缩掉列
    denmat = numpy.matmul(mat, mat.transpose())
    #把密度矩阵再分成相同粒子数在一起的小块
    #这时就不需要到superblock上面的idx了,需要从phi^phi_idx-1,s^phi_idx
    #到leftext的idx
    spsec_mat_dict = get_density_in_sector(leftstorage, lidxs, denmat)
    #获得更新基的phival
    #这个过程就是给每一个denmat的subblock对角化,注意phival最后会
    #放到整个leftext的基上面去
    phival = get_phival_from_density_sector(leftstorage, spsec_mat_dict,
                                            maxkeep)
    #现在给leftblockext升级成新的位置上面的ext
    #先从leftblkext升级到left + 1
    leftext = leftstorage.block
    newleftblk = update_to_leftblock(leftext, phival)
    #然后升级哈密顿量
    newham = update_leftblockextend_hamiltonian(newleftblk,
                                                leftstorage.hamiltonian,
                                                phival)
    #调整一下tmp中的idx,没有实际的价值
    conf.left_tmp_reset(phi_idx, newleftblk, None)
    #先把newleftblk上面的算符升级,然后再扩展
    maintain_dict = {}
    for extidx in leftstorage.oper_storage_list:
        extup = leftstorage.get_oper(extidx, 1)
        newup = update_leftblockextend_oper(newleftblk, extup, phival)
        extdn = leftstorage.get_oper(extidx, -1)
        newdn = update_leftblockextend_oper(newleftblk, extdn, phival)
        maintain_dict[extidx] = (newup, newdn)
    #完成phi_idx位置上的leftblock,开始扩展它到leftblockextend
    newleftext = extend_leftblock(newleftblk)
    #把哈密顿量也扩展
    newhamext = extend_leftblock_hamiltonian(newham, newleftext)
    #以后的观测需要的算符,从leftext[phi_idx-1]中拿到,再升级扩展
    #以后放到leftext[phi_idx]中
    ext_meaops = {}
    for prefix, stidx in measure_storage:
        if stidx == phi_idx + 1:  #如果是新加的格子上的算符,不需要升级
            #新建一个观测用的算符
            meaop = create_operator_of_site(newleftext.stbss,
                                            OperFactory.create_by_name(prefix))
            #扩展到leftext[phi_idx]上
            meaop = leftsite_extend_oper(newleftext, meaop)
        else:
            #得到meaop
            meaop = leftstorage.get_meas(prefix, stidx)
            #升级meaop到leftblock[phi_idx]
            meaop = update_leftblockextend_oper(newleftblk, meaop, phival)
            #扩展
            meaop = leftblock_extend_oper(newleftext, meaop)
        ext_meaops['%s,%d' % (prefix, stidx)] = meaop
    #把现在的缓存进去
    conf.leftext_reset(phi_idx, newleftext)
    conf.storage_leftext_ham(phi_idx, newhamext)
    #获得新加的格子的两个算符并且扩展
    newsiteup = create_operator_of_site(newleftext.stbss,
                                        OperFactory.create_spinup())
    newsitedn = create_operator_of_site(newleftext.stbss,
                                        OperFactory.create_spindown())
    newsiteup = leftsite_extend_oper(newleftext, newsiteup)
    newsitedn = leftsite_extend_oper(newleftext, newsitedn)
    #把之前存的升级到newleftblk上的算符也扩展了
    for idx in maintain_dict:
        extup, extdn = maintain_dict[idx]
        extup = leftblock_extend_oper(newleftext, extup)
        extdn = leftblock_extend_oper(newleftext, extdn)
        maintain_dict[idx] = (extup, extdn)
    #新加的site是phi_idx + 1
    maintain_dict[phi_idx + 1] = (newsiteup, newsitedn)
    #把新的hopping项加进去
    for bnd in newbonds:
        coef_t = conf.model.get_t_coef(bnd, newsiteup.siteidx)
        newhamext.add_hopping_term(maintain_dict[bnd][0], newsiteup, coef_t)
        newhamext.add_hopping_term(maintain_dict[bnd][1], newsitedn, coef_t)
    #把新的格子的U项添加进去
    newiu = create_operator_of_site(newleftext.stbss, OperFactory.create_u())
    newiu = leftsite_extend_oper(newleftext, newiu)
    newhamext.add_u_term(newiu, conf.model.coef_u)
    #把新的格子的Mu项添加进去
    coef_mu = conf.model.get_coef_mu(phi_idx + 1)
    if coef_mu != 0:
        newnu = create_operator_of_site(newleftext.stbss,
                                        OperFactory.create_numup())
        newnu = leftsite_extend_oper(newleftext, newnu)
        newhamext.add_mu_term(newnu, coef_mu)
        newnd = create_operator_of_site(newleftext.stbss,
                                        OperFactory.create_numdown())
        newnd = leftsite_extend_oper(newleftext, newnd)
        newhamext.add_mu_term(newnd, coef_mu)
    #保存需要保存的算符
    for extidx in extoper_storage:
        conf.storage_leftext_oper(phi_idx, maintain_dict[extidx][0])
        conf.storage_leftext_oper(phi_idx, maintain_dict[extidx][1])
    #把需要保存的观测用的算符保存到leftext[phi_idx]当中
    leftstor_phiidx = conf.get_leftext_storage(phi_idx)
    for prefix, stidx in measure_storage:
        meaop = ext_meaops['%s,%d' % (prefix, stidx)]
        leftstor_phiidx.storage_meas(prefix, meaop)
    return ground_erg
コード例 #4
0
def prepare_rightblockextend(conf: DMRGConfig, phi_idx: int,
                             newbonds: List[int], extoper_storage: List[int],
                             measure_storage: List[Tuple[str, int]]):
    '''把最右边的一个格子的扩展计算出来,这个扩展要包括新增的hopping\n
    以后要用来构成superblock
    '''
    #这个过程不会更新conf中的right_tmp
    rightstorage = conf.get_rightblock_storage(phi_idx)
    right = rightstorage.block
    rightham = rightstorage.hamiltonian
    #扩展right
    rightext = extend_rightblock(right)
    #给conf中的rightext进行初始化
    conf.rightext_reset(phi_idx, rightext)
    #扩展哈密顿量
    rightham = extend_rightblock_hamiltonian(rightham, rightext)
    #把扩展以后的哈密顿量存下来
    conf.storage_rightext_ham(phi_idx, rightham)
    #把需要扩展的算符扩展
    maintain_opers = {}
    #首先考虑这次新加进来的两个
    newup = create_operator_of_site(rightext.stbss,
                                    OperFactory.create_spinup())
    newup = rightsite_extend_oper(rightext, newup)
    newdown = create_operator_of_site(rightext.stbss,
                                      OperFactory.create_spindown())
    newdown = rightsite_extend_oper(rightext, newdown)
    #先把他放到maintain_opers当中
    maintain_opers[rightext.stbss.sites[0]] = (newup, newdown)
    #然后把现在暂存的这些都扩展并保存到maintain_oper
    #中,这些可能会去要计算bond,还有可能会保存到rightext
    while len(rightstorage.oper_storage_list) > 0:
        stidx = rightstorage.oper_storage_list[0]
        #弹出这两个算符
        stup, stdown = rightstorage.pop_oper(stidx)
        #扩展这两个算符,然后放到maintain_opers
        stup = rightblock_extend_oper(rightext, stup)
        stdown = rightblock_extend_oper(rightext, stdown)
        maintain_opers[stidx] = (stup, stdown)
    #把需要保存到ext中的算符都保存下来
    for stidx in extoper_storage:
        conf.storage_rightext_oper(phi_idx, maintain_opers[stidx][0])
        conf.storage_rightext_oper(phi_idx, maintain_opers[stidx][1])
    #把新的bond添加进去
    #rightext中保存的是rightham的实例,在这时修改也是可以的
    for bstidx in newbonds:
        coef_t = conf.model.get_t_coef(bstidx, newup.siteidx)
        #自旋向上部分
        tar_up = maintain_opers[bstidx][0]
        rightham.add_hopping_term(tar_up, newup, coef_t)
        #自旋向下部分
        tar_down = maintain_opers[bstidx][1]
        rightham.add_hopping_term(tar_down, newdown, coef_t)
    #把新的U添加进去
    newu = create_operator_of_site(rightext.stbss, OperFactory.create_u())
    newu = rightsite_extend_oper(rightext, newu)
    rightham.add_u_term(newu, conf.model.coef_u)
    #把新的Mu项添加进去
    coef_mu = conf.model.get_coef_mu(phi_idx - 1)
    if coef_mu != 0:
        newnu = create_operator_of_site(rightext.stbss,
                                        OperFactory.create_numup())
        newnu = rightsite_extend_oper(rightext, newnu)
        rightham.add_mu_term(newnu, coef_mu)
        newnd = create_operator_of_site(rightext.stbss,
                                        OperFactory.create_numdown())
        newnd = rightsite_extend_oper(rightext, newnd)
        rightham.add_mu_term(newnd, coef_mu)
    #把扩展后的算符存储到rightext[N]上面,用来给以后的观测使用
    #之前的过程并没有调整right_tmp,直接用就可以了
    rightext_stor = conf.get_rightext_storage(phi_idx)
    for prefix, idx in measure_storage:
        if idx == phi_idx - 1:  #如果是新加的格子,就新建这个算符
            meaop = create_operator_of_site(rightext.stbss,
                                            OperFactory.create_by_name(prefix))
            meaop = rightsite_extend_oper(rightext, meaop)
        else:
            meaop = rightstorage.get_meas(prefix, idx)
            meaop = rightblock_extend_oper(rightext, meaop)
        rightext_stor.storage_meas(prefix, meaop)
    return rightext
コード例 #5
0
def rightblockextend_to_next(conf: DMRGConfig, phi_idx: int,
                             extrabonds: List[int], newbonds: List[int],
                             extoper_storage: List[int],
                             measure_storage: List[Tuple[str, int]],
                             spin_sector, maxkeep: int):
    '''这时候的phi_idx是新的rightext的idx,leftext的idx就是他减去2\n
    spin_sector是在superblock上面的粒子数的要求\n
    extrabond在get_superblock_ham中要使用,而newbonds是值扩展
    '''
    #首先要将superblock得到,这个时候左边和右边之间的
    #extrabond也要考虑上
    leftstorage = conf.get_leftext_storage(phi_idx - 2)
    rightstorage = conf.get_rightext_storage(phi_idx + 1)
    #scrtor_idxs中保存的是满足粒子数要求的所有superblock上的基的idx
    #mat是这个sector上的矩阵
    sector_idxs, mat, superext = get_superblock_ham(conf.model, leftstorage,
                                                    rightstorage, spin_sector,
                                                    extrabonds)
    #将基态解出来
    eigvals, eigvecs = scipy.sparse.linalg.eigsh(mat, k=1, which='SA')
    #numpy.linalg.eigh(mat)
    ground = eigvecs[:, 0]
    ground_erg = eigvals[0]
    #把基态的信息保留下来
    conf.ground_vec = ground
    conf.ground_secidx = sector_idxs
    conf.ground_superext = superext
    #print('g', ground_erg)
    #从基态构造密度矩阵
    #这里需要sector_idx来判断有哪些位置上是有数值的
    #这个方法主要是将基态的C(alpha,s^j,s^j+1,beta)这个写成
    #M(a,b),lidxs就是将a变成(alpha,s^j)的列表,
    #ridxs是b到(s^j+1,beta)的,这在以后计算phival的时候有作用
    #因为phival的列是在(s^j+1,beta)的
    lidxs, ridxs, mat = get_density_root(  #pylint: disable=unused-variable
        leftstorage, rightstorage, sector_idxs, ground)
    #right上面的密度矩阵的获得
    denmat = numpy.matmul(mat.transpose(), mat)
    #这个方法主要目的是把density matrix划分成小块
    spsec_mat_dict = get_density_in_sector(rightstorage, ridxs, denmat)
    #获得phival
    phival = get_phival_from_density_sector(rightstorage, spsec_mat_dict,
                                            maxkeep)
    #在获得了phival以后,就可以通过这个phival更新基
    #rightblock^phi_idx里面的内容全部都在rightblockextend^phi_idx+1里面
    #不需要添加,只需要升级就行了,在DMRG sweep的过程中,rightblock上面的
    #算符或者哈密顿量都是用不到的,不进行保存
    rightext = rightstorage.block
    newrightblk = update_to_rightblock(rightext, phival)
    newham = update_rightblockextend_hamiltonian(newrightblk,
                                                 rightstorage.hamiltonian,
                                                 phival)
    #设置一下现在的idx,不保存哈密顿量,以后用不到
    conf.right_tmp_reset(phi_idx, newrightblk, None)
    #用来保存newrightblk上面的算符
    maintain_dict = {}
    #把需要放到新的rightext上面的算符,先升级到新的right上面
    for extidx in rightstorage.oper_storage_list:  #extoper_storage:
        #上一次迭代的时候,包含小于phi_val的bond的site都被存在
        #conf里面了
        extup = rightstorage.get_oper(extidx, 1)
        newup = update_rightblockextend_oper(newrightblk, extup, phival)
        extdn = rightstorage.get_oper(extidx, -1)
        newdn = update_rightblockextend_oper(newrightblk, extdn, phival)
        maintain_dict[extidx] = (newup, newdn)
    #把新的rightblock扩展一个格子
    newrightext = extend_rightblock(newrightblk)
    #把哈密顿量也扩展一个格子
    newhamext = extend_rightblock_hamiltonian(newham, newrightext)
    #以后的观测需要的算符,从leftext[phi_idx-1]中拿到,再升级扩展
    #以后放到leftext[phi_idx]中
    ext_meaops = {}
    for prefix, stidx in measure_storage:
        if stidx == phi_idx - 1:  #如果是新加的格子上的算符,不需要升级
            #新建一个观测用的算符
            meaop = create_operator_of_site(newrightext.stbss,
                                            OperFactory.create_by_name(prefix))
            #扩展到leftext[phi_idx]上
            meaop = rightsite_extend_oper(newrightext, meaop)
        else:
            #得到meaop
            meaop = rightstorage.get_meas(prefix, stidx)
            #升级meaop到leftblock[phi_idx]
            meaop = update_rightblockextend_oper(newrightblk, meaop, phival)
            #扩展
            meaop = rightblock_extend_oper(newrightext, meaop)
        ext_meaops['%s,%d' % (prefix, stidx)] = meaop
    #更新缓存的ext,现在存进去就行了,后面在add_hopping_term
    #也是加在这个newhamext上面的
    conf.rightext_reset(phi_idx, newrightext)
    conf.storage_rightext_ham(phi_idx, newhamext)
    #获得新加的格子上面的两个算符
    newsiteup = create_operator_of_site(newrightext.stbss,
                                        OperFactory.create_spinup())
    newsitedn = create_operator_of_site(newrightext.stbss,
                                        OperFactory.create_spindown())
    #扩展到新的基上
    newsiteup = rightsite_extend_oper(newrightext, newsiteup)
    newsitedn = rightsite_extend_oper(newrightext, newsitedn)
    #maintain_dict[phi_idx-1] = (newsiteup, newsitedn)
    #把maintain_dict中的其他算符也扩展到新的基上
    for idx in maintain_dict:
        extup, extdn = maintain_dict[idx]
        extup = rightblock_extend_oper(newrightext, extup)
        extdn = rightblock_extend_oper(newrightext, extdn)
        maintain_dict[idx] = (extup, extdn)
    maintain_dict[phi_idx - 1] = (newsiteup, newsitedn)
    #加入新的hopping项
    for bnd in newbonds:
        coef_t = conf.model.get_t_coef(bnd, newsiteup.siteidx)
        newhamext.add_hopping_term(maintain_dict[bnd][0], newsiteup, coef_t)
        newhamext.add_hopping_term(maintain_dict[bnd][1], newsitedn, coef_t)
    #把新的格子的U项添加进去
    newiu = create_operator_of_site(newrightext.stbss, OperFactory.create_u())
    newiu = rightsite_extend_oper(newrightext, newiu)
    newhamext.add_u_term(newiu, conf.model.coef_u)
    #把新的格子的Mu项添加进去
    coef_mu = conf.model.get_coef_mu(phi_idx - 1)
    if coef_mu != 0:
        newnu = create_operator_of_site(newrightext.stbss,
                                        OperFactory.create_numup())
        newnu = rightsite_extend_oper(newrightext, newnu)
        newhamext.add_mu_term(newnu, coef_mu)
        newnd = create_operator_of_site(newrightext.stbss,
                                        OperFactory.create_numdown())
        newnd = rightsite_extend_oper(newrightext, newnd)
        newhamext.add_mu_term(newnd, coef_mu)
    #保存需要保存的新的ext上面的算符
    for extidx in extoper_storage:
        conf.storage_rightext_oper(phi_idx, maintain_dict[extidx][0])
        conf.storage_rightext_oper(phi_idx, maintain_dict[extidx][1])
    #把需要保存的观测用的算符保存到leftext[phi_idx]当中
    rightstor_phiidx = conf.get_rightext_storage(phi_idx)
    for prefix, stidx in measure_storage:
        meaop = ext_meaops['%s,%d' % (prefix, stidx)]
        rightstor_phiidx.storage_meas(prefix, meaop)
    return ground_erg