コード例 #1
0
ファイル: addons.py プロジェクト: raybrad/pyscf
def label_orb_symm(mol, irrep_name, symm_orb, mo, s=None, check=True):
    '''Label the symmetry of given orbitals

    irrep_name can be either the symbol or the ID of the irreducible
    representation.  If the ID is provided, it returns the numeric code
    associated with XOR operator, see :py:meth:`symm.param.IRREP_ID_TABLE`

    Args:
        mol : an instance of :class:`Mole`

        irrep_name : list of str or int
            A list of irrep ID or name,  it can be either mol.irrep_id or
            mol.irrep_name.  It can affect the return "label".
        symm_orb : list of 2d array
            the symmetry adapted basis
        mo : 2d array
            the orbitals to label

    Returns:
        list of symbols or integers to represent the irreps for the given
        orbitals

    Examples:

    >>> from pyscf import gto, scf, symm
    >>> mol = gto.M(atom='H 0 0 0; H 0 0 1', basis='ccpvdz',verbose=0, symmetry=1)
    >>> mf = scf.RHF(mol)
    >>> mf.kernel()
    >>> symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mf.mo_coeff)
    ['Ag', 'B1u', 'Ag', 'B1u', 'B2u', 'B3u', 'Ag', 'B2g', 'B3g', 'B1u']
    >>> symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mf.mo_coeff)
    [0, 5, 0, 5, 6, 7, 0, 2, 3, 5]
    '''
    nmo = mo.shape[1]
    if s is None:
        s = mol.intor_symmetric('cint1e_ovlp_sph')
    mo_s = numpy.dot(mo.T, s)
    norm = numpy.empty((len(irrep_name), nmo))
    for i,ir in enumerate(irrep_name):
        moso = numpy.dot(mo_s, symm_orb[i])
        norm[i] = numpy.einsum('ij,ij->i', moso, moso)
    iridx = numpy.argmax(norm, axis=0)
    orbsym = [irrep_name[i] for i in iridx]
    logger.debug(mol, 'irreps of each MO %s', str(orbsym))
    if check:
        norm[iridx,numpy.arange(nmo)] = 0
        orbidx = numpy.where(norm > THRESHOLD)
        if orbidx[1].size > 0:
            idx = numpy.where(norm > THRESHOLD*1e2)
            if idx[1].size > 0:
                logger.error(mol, 'orbitals %s not symmetrized, norm = %s',
                             idx[1], norm[idx])
                raise ValueError('orbitals %s not symmetrized' % idx[1])
            else:
                logger.warn(mol, 'orbitals %s not strictly symmetrized.',
                            orbidx[1])
                logger.warn(mol, 'They can be symmetrized with '
                            'pyscf.symm.symmetrize_orb function.')
                logger.debug(mol, 'norm = %s', norm[orbidx])
    return orbsym
コード例 #2
0
ファイル: nevpt2.py プロジェクト: pengdl/pyscf
    def compress_approx(self,maxM=500, compress_schedule=None, tol=1e-7, stored_integral =False):
        '''SC-NEVPT2 with compressed perturber

        Kwargs :
            maxM : int
                DMRG bond dimension

        Examples:

        >>> mf = gto.M('N 0 0 0; N 0 0 1.4', basis='6-31g').apply(scf.RHF).run()
        >>> mc = dmrgscf.DMRGSCF(mf, 4, 4).run()
        >>> NEVPT(mc, root=0).compress_approx(maxM=100).kernel()
        -0.14058324991532101
        '''
        #TODO
        #Some preprocess for compressed perturber
        if hasattr(self.fcisolver, 'nevpt_intermediate'):
            logger.info(self, 'Use compressed mps perturber as an aaproximation')
        else:
            logger.error(self, 'Compressed mps perturber can be only used for DMRG wave function')
            exit()

        from pyscf.dmrgscf.nevpt_mpi import DMRG_COMPRESS_NEVPT
        if stored_integral: #Stored perturbation integral and read them again. For debugging purpose.
            DMRG_COMPRESS_NEVPT('nevpt_perturb_integral',maxM= maxM, root= self.root, nevptsolver= compress_schedule, tol= tol)
        else:
            DMRG_COMPRESS_NEVPT(self,maxM= maxM, root= self.root, nevptsolver= compress_schedule, tol= tol)

        self.canonicalized = True
        self.compressed_mps = True
        return self
コード例 #3
0
ファイル: nevpt2.py プロジェクト: chrinide/pyscf
    def compress_approx(self,maxM=500, nevptsolver=None, tol=1e-7, stored_integral =False):
        '''SC-NEVPT2 with compressed perturber

        Kwargs :
            maxM : int
                DMRG bond dimension

        Examples:

        >>> mf = gto.M('N 0 0 0; N 0 0 1.4', basis='6-31g').apply(scf.RHF).run()
        >>> mc = dmrgscf.DMRGSCF(mf, 4, 4).run()
        >>> NEVPT(mc, root=0).compress_approx(maxM=100).kernel()
        -0.14058324991532101
        '''
        #TODO
        #Some preprocess for compressed perturber
        if getattr(self.fcisolver, 'nevpt_intermediate', None):
            logger.info(self, 'Use compressed mps perturber as an approximation')
        else:
            msg = 'Compressed mps perturber can be only used with DMRG wave function'
            logger.error(self, msg)
            raise RuntimeError(msg)

        self.nevptsolver = nevptsolver
        self.maxM = maxM
        self.tol = tol
        self.stored_integral = stored_integral

        self.canonicalized = True
        self.compressed_mps = True
        return self
コード例 #4
0
    def compress_approx(self,maxM=500, nevptsolver=None, tol=1e-7, stored_integral =False):
        '''SC-NEVPT2 with compressed perturber

        Kwargs :
            maxM : int
                DMRG bond dimension

        Examples:

        >>> mf = gto.M('N 0 0 0; N 0 0 1.4', basis='6-31g').apply(scf.RHF).run()
        >>> mc = dmrgscf.DMRGSCF(mf, 4, 4).run()
        >>> NEVPT(mc, root=0).compress_approx(maxM=100).kernel()
        -0.14058324991532101
        '''
        #TODO
        #Some preprocess for compressed perturber
        if hasattr(self.fcisolver, 'nevpt_intermediate'):
            logger.info(self, 'Use compressed mps perturber as an approximation')
        else:
            msg = 'Compressed mps perturber can be only used with DMRG wave function'
            logger.error(self, msg)
            raise RuntimeError(msg)

        self.nevptsolver = nevptsolver
        self.maxM = maxM
        self.tol = tol
        self.stored_integral = stored_integral

        self.canonicalized = True
        self.compressed_mps = True
        return self
コード例 #5
0
ファイル: uhf_symm.py プロジェクト: diradical/pyscf
 def dump_flags(self):
     hf.SCF.dump_flags(self)
     logger.info(self, '%s with symmetry adapted basis',
                 self.__class__.__name__)
     float_irname = []
     fix_na = 0
     fix_nb = 0
     for ir in range(self.mol.symm_orb.__len__()):
         irname = self.mol.irrep_name[ir]
         if irname in self.irrep_nelec:
             fix_na += self.irrep_nelec[irname][0]
             fix_nb += self.irrep_nelec[irname][1]
         else:
             float_irname.append(irname)
     float_irname = set(float_irname)
     if fix_na+fix_nb > 0:
         logger.info(self, 'fix %d electrons in irreps: %s',
                     fix_na+fix_nb, str(self.irrep_nelec.items()))
         if ((fix_na+fix_nb > self.mol.nelectron) or
             (fix_na>self.nelectron_alpha) or
             (fix_nb+self.nelectron_alpha>self.mol.nelectron)):
             logger.error(self, 'electron number error in irrep_nelec %s',
                          self.irrep_nelec.items())
             raise ValueError('irrep_nelec')
     if float_irname:
         logger.info(self, '%d free electrons in irreps %s',
                     self.mol.nelectron-fix_na-fix_nb,
                     ' '.join(float_irname))
     elif fix_na+fix_nb != self.mol.nelectron:
         logger.error(self, 'electron number error in irrep_nelec %d',
                      self.irrep_nelec.items())
         raise ValueError('irrep_nelec')
コード例 #6
0
ファイル: hf_symm.py プロジェクト: v1j4y/pyscf
 def dump_flags(self):
     hf.RHF.dump_flags(self)
     logger.info(self, '%s with symmetry adapted basis',
                 self.__class__.__name__)
     float_irname = []
     fix_ne = 0
     for ir in range(self.mol.symm_orb.__len__()):
         irname = self.mol.irrep_name[ir]
         if irname in self.irrep_nelec:
             fix_ne += self.irrep_nelec[irname]
         else:
             float_irname.append(irname)
     if fix_ne > 0:
         logger.info(self, 'fix %d electrons in irreps %s',
                     fix_ne, self.irrep_nelec.items())
         if fix_ne > self.mol.nelectron:
             logger.error(self, 'num. electron error in irrep_nelec %s',
                          self.irrep_nelec.items())
             raise ValueError('irrep_nelec')
     if float_irname:
         logger.info(self, '%d free electrons in irreps %s',
                     self.mol.nelectron-fix_ne, ' '.join(float_irname))
     elif fix_ne != self.mol.nelectron:
         logger.error(self, 'number of electrons error in irrep_nelec %s',
                      self.irrep_nelec.items())
         raise ValueError('irrep_nelec')
コード例 #7
0
ファイル: pipek.py プロジェクト: sunqm/pyscf-test
    def atomic_pops(self, mol, mo_coeff, method=None):
        if method is None:
            method = self.pop_method

        if method.lower() in ('iao', 'ibo') and self._scf is None:
            logger.error(self, 'PM with IAO scheme should include an scf '
                         'object when creating PM object.\n    PM(mol, mf=scf_object)')
            raise ValueError('PM attribute method is not valid')
        return atomic_pops(mol, mo_coeff, method, self._scf)
コード例 #8
0
def executeSHCI(SHCI):
    outFile = os.path.join(SHCI.runtimeDir, SHCI.outputFile)
    try:
        cmd = ' '.join((SHCI.mpiprefix, SHCI.executable))
        cmd = "%s >> %s" % (cmd, outFile)
        check_call(cmd, shell=True)
    except CalledProcessError as err:
        logger.error(SHCI, cmd)
        raise err
コード例 #9
0
def executeBLOCK(DMRGCI):

    inFile = os.path.join(DMRGCI.runtimeDir, DMRGCI.configFile)
    outFile = os.path.join(DMRGCI.runtimeDir, DMRGCI.outputFile)
    try:
        cmd = ' '.join((DMRGCI.mpiprefix, DMRGCI.executable, inFile))
        cmd = "%s > %s 2>&1" % (cmd, outFile)
        check_call(cmd, shell=True)
    except CalledProcessError as err:
        logger.error(DMRGCI, cmd)
        raise err
コード例 #10
0
ファイル: dmrgci.py プロジェクト: pengdl/pyscf
def executeBLOCK(DMRGCI):

    inFile  = os.path.join(DMRGCI.runtimeDir, DMRGCI.configFile)
    outFile = os.path.join(DMRGCI.runtimeDir, DMRGCI.outputFile)
    try:
        cmd = ' '.join((DMRGCI.mpiprefix, DMRGCI.executable, inFile))
        cmd = "%s > %s 2>&1" % (cmd, outFile)
        check_call(cmd, shell=True)
    except CalledProcessError as err:
        logger.error(DMRGCI, cmd)
        raise err
コード例 #11
0
ファイル: dmrgci.py プロジェクト: biruce-fm/pyscf
def executeBLOCK(DMRGCI):

    inFile  = DMRGCI.configFile
    outFile = DMRGCI.outputFile
    try:
        cmd = ' '.join((DMRGCI.mpiprefix, DMRGCI.executable, inFile))
        cmd = "%s > %s 2>&1" % (cmd, outFile)
        check_call(cmd, cwd=DMRGCI.runtimeDir, shell=True)
    except CalledProcessError as err:
        logger.error(DMRGCI, cmd)
        DMRGCI.stdout.write(check_output(['tail', '-100', outFile]))
        raise err
コード例 #12
0
ファイル: shci.py プロジェクト: qiangzhongwork/pyscf
def executeSHCI(SHCI):
    file1 = os.path.join(SHCI.runtimeDir, "%s/shci.e" % (SHCI.prefix))
    if os.path.exists(file1):
        os.remove(file1)
    inFile = os.path.join(SHCI.runtimeDir, SHCI.configFile)
    outFile = os.path.join(SHCI.runtimeDir, SHCI.outputFile)
    try:
        cmd = ' '.join((SHCI.mpiprefix, SHCI.executable, inFile))
        cmd = "%s > %s 2>&1" % (cmd, outFile)
        check_call(cmd, shell=True)
    except CalledProcessError as err:
        logger.error(SHCI, cmd)
        raise err
コード例 #13
0
ファイル: dmrgci.py プロジェクト: sunqm/pyscf
def executeBLOCK(DMRGCI):

    inFile  = DMRGCI.configFile
    outFile = DMRGCI.outputFile
    try:
        cmd = ' '.join((DMRGCI.mpiprefix, DMRGCI.executable, inFile))
        cmd = "%s > %s 2>&1" % (cmd, outFile)
        check_call(cmd, cwd=DMRGCI.runtimeDir, shell=True)
    except CalledProcessError as err:
        logger.error(DMRGCI, cmd)
        outFile = os.path.join(DMRGCI.runtimeDir, outFile)
        DMRGCI.stdout.write(check_output(['tail', '-100', outFile]).decode())
        raise err
コード例 #14
0
ファイル: shci.py プロジェクト: zwgsyntax/pyscf
def execute_shci(shciobj):
    output = os.path.join(shciobj.runtimedir, shciobj.outputfile)
    cmd = ' '.join((shciobj.mpiprefix, shciobj.executable))
    try:
        #cmd = ' '.join((shciobj.mpiprefix, shciobj.executable))
        #cmd = "%s > %s 2>&1" % (cmd, output)
        #check_call(cmd, shell=True, cwd=shciobj.runtimedir)
        with open(output, 'w') as f:
            check_call(cmd.split(), cwd=shciobj.runtimedir, stdout=f, stderr=f)
    except CalledProcessError as err:
        logger.error(shciobj, cmd)
        shciobj.stdout.write(check_output(['tail', '-100', output]))
        raise err
    return output
コード例 #15
0
ファイル: shci.py プロジェクト: chrinide/pyscf
def execute_shci(shciobj):
    output = os.path.join(shciobj.runtimedir, shciobj.outputfile)
    cmd = ' '.join((shciobj.mpiprefix, shciobj.executable))
    try:
        #cmd = ' '.join((shciobj.mpiprefix, shciobj.executable))
        #cmd = "%s > %s 2>&1" % (cmd, output)
        #check_call(cmd, shell=True, cwd=shciobj.runtimedir)
        with open(output, 'w') as f:
            check_call(cmd.split(), cwd=shciobj.runtimedir, stdout=f, stderr=f)
    except CalledProcessError as err:
        logger.error(shciobj, cmd)
        shciobj.stdout.write(check_output(['tail', '-100', output]))
        raise err
    return output
コード例 #16
0
ファイル: nevpt2.py プロジェクト: v1j4y/pyscf
    def compress_approx(self,maxM=500, compress_schedule=None, tol=1e-7, stored_integral =False):
        #TODO
        #Some preprocess for compressed perturber
        if hasattr(self.fcisolver, 'nevpt_intermediate'):
            logger.info(self, 'Use compressed mps perturber as an aaproximation')
        else:
            logger.error(self, 'Compressed mps perturber can be only used for DMRG wave function')
            exit()

        from pyscf.dmrgscf.nevpt_mpi import DMRG_COMPRESS_NEVPT
        if stored_integral: #Stored perturbation integral and read them again. For debugging purpose.
            DMRG_COMPRESS_NEVPT('nevpt_perturb_integral',maxM= maxM, root= self.root, nevptsolver= compress_schedule, tol= tol)
        else:
            DMRG_COMPRESS_NEVPT(self,maxM= maxM, root= self.root, nevptsolver= compress_schedule, tol= tol)

        self.canonicalized = True
        self.compressed_mps = True
        return self
コード例 #17
0
ファイル: nevpt2.py プロジェクト: verena-neufeld/pyscf
    def compress_approx(self,
                        maxM=500,
                        nevptsolver=None,
                        tol=1e-7,
                        stored_integral=False):
        '''SC-NEVPT2 with compressed perturber

        Kwargs :
            maxM : int
                DMRG bond dimension

        Examples:

        >>> mf = gto.M('N 0 0 0; N 0 0 1.4', basis='6-31g').apply(scf.RHF).run()
        >>> mc = dmrgscf.DMRGSCF(mf, 4, 4).run()
        >>> NEVPT(mc, root=0).compress_approx(maxM=100).kernel()
        -0.14058324991532101

        References:

        J. Chem. Theory Comput. 12, 1583 (2016), doi:10.1021/acs.jctc.5b01225

        J. Chem. Phys. 146, 244102 (2017), doi:10.1063/1.4986975
        '''
        #TODO
        #Some preprocess for compressed perturber
        if getattr(self.fcisolver, 'nevpt_intermediate', None):
            logger.info(self,
                        'Use compressed mps perturber as an approximation')
        else:
            msg = 'Compressed mps perturber can be only used with DMRG wave function'
            logger.error(self, msg)
            raise RuntimeError(msg)

        self.nevptsolver = nevptsolver
        self.maxM = maxM
        self.tol = tol
        self.stored_integral = stored_integral

        self.canonicalized = True
        self.compressed_mps = True
        self.for_dmrg()
        return self
コード例 #18
0
def runQDPT(mc, gtensor):
    if mc.fcisolver.__class__.__name__ == 'FakeCISolver':
        SHCI = mc.fcisolver.fcisolvers[0]
        outFile = os.path.join(SHCI.runtimeDir, SHCI.outputFile)
        writeSHCIConfFile(SHCI, mc.nelecas, False)
        confFile = os.path.join(SHCI.runtimeDir, SHCI.configFile)
        f = open(confFile, 'a')
        for SHCI2 in mc.fcisolver.fcisolvers[1:]:
            if (SHCI2.prefix != ""):
                f.write('prefix %s\n' % (SHCI2.prefix))
        if (gtensor):
            f.write("dogtensor\n")
        f.close()
        try:
            cmd = ' '.join((SHCI.mpiprefix, SHCI.QDPTexecutable, confFile))
            cmd = "%s > %s 2>&1" % (cmd, outFile)
            check_call(cmd, shell=True)
            check_call('cat %s|grep -v "#"' % (outFile), shell=True)
        except CalledProcessError as err:
            logger.error(mc.fcisolver, cmd)
            raise err

    else:
        writeSHCIConfFile(mc.fcisolver, mc.nelecas, False)
        confFile = os.path.join(mc.fcisolver.runtimeDir,
                                mc.fcisolver.configFile)
        outFile = os.path.join(mc.fcisolver.runtimeDir,
                               mc.fcisolver.outputFile)
        if (gtensor):
            f = open(confFile, 'a')
            f.write("dogtensor\n")
            f.close()
        try:
            cmd = ' '.join((mc.fcisolver.mpiprefix,
                            mc.fcisolver.QDPTexecutable, confFile))
            cmd = "%s > %s 2>&1" % (cmd, outFile)
            check_call(cmd, shell=True)
            check_call('cat %s|grep -v "#"' % (outFile), shell=True)
        except CalledProcessError as err:
            logger.error(mc.fcisolver, cmd)
            raise err
コード例 #19
0
ファイル: hf_symm.py プロジェクト: v1j4y/pyscf
    def dump_flags(self):
        rohf.ROHF.dump_flags(self)
        logger.info(self, '%s with symmetry adapted basis',
                    self.__class__.__name__)
#TODO: improve the sainity check
        float_irname = []
        fix_na = 0
        fix_nb = 0
        for ir in range(self.mol.symm_orb.__len__()):
            irname = self.mol.irrep_name[ir]
            if irname in self.irrep_nelec:
                if isinstance(self.irrep_nelec[irname], (int, numpy.integer)):
                    nb = self.irrep_nelec[irname] // 2
                    fix_na += self.irrep_nelec[irname] - nb
                    fix_nb += nb
                else:
                    fix_na += self.irrep_nelec[irname][0]
                    fix_nb += self.irrep_nelec[irname][1]
            else:
                float_irname.append(irname)
        float_irname = set(float_irname)
        if fix_na+fix_nb > 0:
            logger.info(self, 'fix %d electrons in irreps: %s',
                        fix_na+fix_nb, str(self.irrep_nelec.items()))
            if ((fix_na+fix_nb > self.mol.nelectron) or
                (fix_na>self.nelec[0]) or (fix_nb>self.nelec[1]) or
                (fix_na+self.nelec[1]>self.mol.nelectron) or
                (fix_nb+self.nelec[0]>self.mol.nelectron)):
                logger.error(self, 'electron number error in irrep_nelec %s',
                             self.irrep_nelec.items())
                raise ValueError('irrep_nelec')
        if float_irname:
            logger.info(self, '%d free electrons in irreps %s',
                        self.mol.nelectron-fix_na-fix_nb,
                        ' '.join(float_irname))
        elif fix_na+fix_nb != self.mol.nelectron:
            logger.error(self, 'electron number error in irrep_nelec %s',
                         self.irrep_nelec.items())
            raise ValueError('irrep_nelec')
コード例 #20
0
 def opt_ci(self):
     for it in range(self.max_cycle[-1]):
         _ci=self.ci; _e_ele = self.e_ele
         for u in range(self.nocc-self.npair_d, self.nocc):
             hp = numpy.zeros((2,2))
             for i in range(2):
                 for j in range(2):
                     hp[i,j] += 2*self.h_mo[self.pair[u,i],self.pair[u,i]]*delta(i,j) \
                                 + self.g_mo[index(self.pair[u,i],self.pair[u,j],self.pair[u,i],self.pair[u,j])]
                     if i==j:
                         for v in range(self.nocc):
                             t=self.t(u,v)
                             if v!=u:
                                 for jj in range(2):
                                     hp[i,j] += _ci[v,jj]**2 * \
                                     (4*self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[v,jj], self.pair[v,jj])]
                                     - 2*t*self.g_mo[index(self.pair[u,i], self.pair[v,jj], self.pair[u,i],self.pair[v,jj])])
             s, a = numpy.linalg.eig(hp)
             a=a[:,numpy.argsort(s.real)]
             self.ci[u,:] = a[:,0].T
         self.e_ele=self.energy_elec()
         if (abs(_e_ele-self.e_ele)<self.conv_tol[-1]): break
     else: logger.error(self, 'Error: Not converge after %d cycles ci optimization' %self.max_cycle[-1])
コード例 #21
0
ファイル: nevpt_mpi.py プロジェクト: chrinide/pyscf
def DMRG_COMPRESS_NEVPT(mc, maxM=500, root=0, nevptsolver=None, tol=1e-7,
                        nevpt_integral=None):

    if isinstance(nevpt_integral, str) and h5py.is_hdf5(nevpt_integral):
        nevpt_integral_file = os.path.abspath(nevpt_integral)
        mol = chkfile.load_mol(nevpt_integral_file)

        fh5 = h5py.File(nevpt_integral_file, 'r')
        ncas = fh5['mc/ncas'].value
        ncore = fh5['mc/ncore'].value
        nvirt = fh5['mc/nvirt'].value
        nelecas = fh5['mc/nelecas'].value
        nroots = fh5['mc/nroots'].value
        wfnsym = fh5['mc/wfnsym'].value
        fh5.close()
    else :
        mol = mc.mol
        ncas = mc.ncas
        ncore = mc.ncore
        nvirt = mc.mo_coeff.shape[1] - mc.ncas-mc.ncore
        nelecas = mc.nelecas
        nroots = mc.fcisolver.nroots
        wfnsym = mc.fcisolver.wfnsym
        nevpt_integral_file = None

    if nevptsolver is None:
        nevptsolver = default_nevpt_schedule(mc.fcisolver, maxM, tol)
        #nevptsolver.__dict__.update(mc.fcisolver.__dict__)
        nevptsolver.wfnsym = wfnsym
        nevptsolver.block_extra_keyword = mc.fcisolver.block_extra_keyword
    nevptsolver.nroots = nroots
    nevptsolver.executable = settings.BLOCKEXE_COMPRESS_NEVPT
    if nevptsolver.executable == getattr(mc.fcisolver, 'executable', None):
        logger.warn(mc, 'DMRG executable file for nevptsolver %s is the same '
                    'to the executable file for DMRG solver %s. If they are '
                    'both compiled by MPI compilers, they may cause error or '
                    'random results in DMRG-NEVPT calculation.')

    nevpt_scratch = os.path.abspath(nevptsolver.scratchDirectory)
    dmrg_scratch = os.path.abspath(mc.fcisolver.scratchDirectory)

    # Integrals are not given by the kwarg nevpt_integral
    if nevpt_integral_file is None:
        nevpt_integral_file = os.path.join(nevpt_scratch, 'nevpt_perturb_integral')
        write_chk(mc, root, nevpt_integral_file)

    conf = dmrgci.writeDMRGConfFile(nevptsolver, nelecas, False, with_2pdm=False,
                                    extraline=['fullrestart','nevpt_state_num %d'%root])
    with open(conf, 'r') as f:
        block_conf = f.readlines()
        block_conf = [l for l in block_conf if 'prefix' not in l]
        block_conf = ''.join(block_conf)

    with h5py.File(nevpt_integral_file) as fh5:
        if 'dmrg.conf' in fh5:
            del(fh5['dmrg.conf'])
        fh5['dmrg.conf'] = block_conf

    if nevptsolver.verbose >= logger.DEBUG1:
        logger.debug1(nevptsolver, 'Block Input conf')
        logger.debug1(nevptsolver, block_conf)

    t0 = (time.clock(), time.time())

    # function nevpt_integral_mpi is called in this cmd
    cmd = ' '.join((nevptsolver.mpiprefix,
                    os.path.realpath(os.path.join(__file__, '..', 'nevpt_mpi.py')),
                    nevpt_integral_file,
                    nevptsolver.executable,
                    dmrg_scratch, nevpt_scratch))
    logger.debug(nevptsolver, 'DMRG_COMPRESS_NEVPT cmd %s', cmd)

    try:
        output = subprocess.check_call(cmd, shell=True)
    except subprocess.CalledProcessError as err:
        logger.error(nevptsolver, cmd)
        raise err

    if nevptsolver.verbose >= logger.DEBUG1:
        logger.debug1(nevptsolver, open(os.path.join(nevpt_scratch, '0', 'dmrg.out')).read())

    perturb_file = os.path.join(nevpt_scratch, '0', 'Perturbation_%d'%root)
    fh5 = h5py.File(perturb_file, 'r')
    Vi_e  =  fh5['Vi/energy'].value
    Vr_e  =  fh5['Vr/energy'].value
    fh5.close()
    logger.note(nevptsolver,'Nevpt Energy:')
    logger.note(nevptsolver,'Sr Subspace:  E = %.14f'%( Vr_e))
    logger.note(nevptsolver,'Si Subspace:  E = %.14f'%( Vi_e))

    logger.timer(nevptsolver,'MPS NEVPT calculation time', *t0)
    return perturb_file
コード例 #22
0
def DMRG_COMPRESS_NEVPT(mc, maxM=500, root=0, nevptsolver=None, tol=1e-7):
    if (isinstance(mc, str)):
        mol = chkfile.load_mol(mc)

        fh5 = h5py.File(mc, 'r')
        ncas = fh5['mc/ncas'].value
        ncore = fh5['mc/ncore'].value
        nvirt = fh5['mc/nvirt'].value
        nelecas = fh5['mc/nelecas'].value
        nroots = fh5['mc/nroots'].value
        wfnsym = fh5['mc/wfnsym'].value
        fh5.close()
        mc_chk = mc
    else :
        mol = mc.mol
        ncas = mc.ncas
        ncore = mc.ncore
        nvirt = mc.mo_coeff.shape[1] - mc.ncas-mc.ncore
        nelecas = mc.nelecas
        nroots = mc.fcisolver.nroots
        wfnsym = mc.fcisolver.wfnsym
        mc_chk = 'nevpt_perturb_integral'
        write_chk(mc, root, mc_chk)

    if nevptsolver is None:
        nevptsolver = default_nevpt_schedule(mol,maxM, tol)
        nevptsolver.wfnsym = wfnsym
        nevptsolver.block_extra_keyword = mc.fcisolver.block_extra_keyword
    nevptsolver.nroots = nroots
    from pyscf.dmrgscf import settings
    nevptsolver.executable = settings.BLOCKEXE_COMPRESS_NEVPT
    scratch = nevptsolver.scratchDirectory
    nevptsolver.scratchDirectory = ''


    dmrgci.writeDMRGConfFile(nevptsolver, nelecas, False, with_2pdm=False,
                             extraline=['fullrestart','nevpt_state_num %d'%root])
    nevptsolver.scratchDirectory = scratch

    if nevptsolver.verbose >= logger.DEBUG1:
        inFile = os.path.join(nevptsolver.runtimeDir, nevptsolver.configFile)
        logger.debug1(nevptsolver, 'Block Input conf')
        logger.debug1(nevptsolver, open(inFile, 'r').read())

    t0 = (time.clock(), time.time())

    cmd = ' '.join((nevptsolver.mpiprefix,
                    '%s/nevpt_mpi.py' % os.path.dirname(os.path.realpath(__file__)),
                    mc_chk,
                    nevptsolver.executable,
                    os.path.join(nevptsolver.runtimeDir, nevptsolver.configFile),
                    nevptsolver.outputFile,
                    nevptsolver.scratchDirectory))
    logger.debug(nevptsolver, 'DMRG_COMPRESS_NEVPT cmd %s', cmd)

    try:
        output = subprocess.check_call(cmd, shell=True)
    except subprocess.CalledProcessError as err:
        logger.error(nevptsolver, cmd)
        raise err

    if nevptsolver.verbose >= logger.DEBUG1:
        logger.debug1(nevptsolver, open(os.path.join(nevptsolver.scratchDirectory, '0/dmrg.out')).read())

    fh5 = h5py.File('Perturbation_%d'%root,'r')
    Vi_e  =  fh5['Vi/energy'].value
    Vr_e  =  fh5['Vr/energy'].value
    fh5.close()
    logger.note(nevptsolver,'Nevpt Energy:')
    logger.note(nevptsolver,'Sr Subspace:  E = %.14f'%( Vr_e))
    logger.note(nevptsolver,'Si Subspace:  E = %.14f'%( Vi_e))

    logger.timer(nevptsolver,'MPS NEVPT calculation time', *t0)
コード例 #23
0
ファイル: nevpt_mpi.py プロジェクト: eronca/pyscf
def DMRG_COMPRESS_NEVPT(mc, maxM=500, root=0, nevptsolver=None, tol=1e-7):
    if (isinstance(mc, str)):
        mol = chkfile.load_mol(mc)

        fh5 = h5py.File(mc, 'r')
        ncas = fh5['mc/ncas'].value
        ncore = fh5['mc/ncore'].value
        nvirt = fh5['mc/nvirt'].value
        nelecas = fh5['mc/nelecas'].value
        nroots = fh5['mc/nroots'].value
        wfnsym = fh5['mc/wfnsym'].value
        fh5.close()
        mc_chk = mc
    else :
        mol = mc.mol
        ncas = mc.ncas
        ncore = mc.ncore
        nvirt = mc.mo_coeff.shape[1] - mc.ncas-mc.ncore
        nelecas = mc.nelecas
        nroots = mc.fcisolver.nroots
        wfnsym = mc.fcisolver.wfnsym
        mc_chk = 'nevpt_perturb_integral'
        write_chk(mc, root, mc_chk)

    if nevptsolver is None:
        nevptsolver = default_nevpt_schedule(mol,maxM, tol)
        nevptsolver.wfnsym = wfnsym
        nevptsolver.block_extra_keyword = mc.fcisolver.block_extra_keyword
    nevptsolver.nroots = nroots
    from pyscf.dmrgscf import settings
    nevptsolver.executable = settings.BLOCKEXE_COMPRESS_NEVPT
    scratch = nevptsolver.scratchDirectory
    nevptsolver.scratchDirectory = ''


    dmrgci.writeDMRGConfFile(nevptsolver, nelecas, False, with_2pdm=False,
                             extraline=['fullrestart','nevpt_state_num %d'%root])
    nevptsolver.scratchDirectory = scratch

    if nevptsolver.verbose >= logger.DEBUG1:
        inFile = os.path.join(nevptsolver.runtimeDir, nevptsolver.configFile)
        logger.debug1(nevptsolver, 'Block Input conf')
        logger.debug1(nevptsolver, open(inFile, 'r').read())

    t0 = (time.clock(), time.time())

    cmd = ' '.join((nevptsolver.mpiprefix,
                    '%s/nevpt_mpi.py' % os.path.dirname(os.path.realpath(__file__)),
                    mc_chk,
                    nevptsolver.executable,
                    nevptsolver.configFile,
                    nevptsolver.outputFile,
                    nevptsolver.scratchDirectory))
    logger.debug(nevptsolver, 'DMRG_COMPRESS_NEVPT cmd %s', cmd)

    try:
        output = subprocess.check_call(cmd, shell=True)
    except subprocess.CalledProcessError as err:
        logger.error(nevptsolver, cmd)
        raise err

    if nevptsolver.verbose >= logger.DEBUG1:
        logger.debug1(nevptsolver, open(os.path.join(nevptsolver.scratchDirectory, '0/dmrg.out')).read())

    fh5 = h5py.File('Perturbation_%d'%root,'r')
    Vi_e  =  fh5['Vi/energy'].value
    Vr_e  =  fh5['Vr/energy'].value
    fh5.close()
    logger.note(nevptsolver,'Nevpt Energy:')
    logger.note(nevptsolver,'Sr Subspace:  E = %.14f'%( Vr_e))
    logger.note(nevptsolver,'Si Subspace:  E = %.14f'%( Vi_e))

    logger.timer(nevptsolver,'MPS NEVPT calculation time', *t0)
コード例 #24
0
ファイル: nevpt_mpi.py プロジェクト: yfyh2013/pyscf
def DMRG_COMPRESS_NEVPT(mc,
                        maxM=500,
                        root=0,
                        nevptsolver=None,
                        tol=1e-7,
                        nevpt_integral=None):
    if nevpt_integral:
        mol = chkfile.load_mol(nevpt_integral)

        fh5 = h5py.File(nevpt_integral, 'r')
        ncas = fh5['mc/ncas'].value
        ncore = fh5['mc/ncore'].value
        nvirt = fh5['mc/nvirt'].value
        nelecas = fh5['mc/nelecas'].value
        nroots = fh5['mc/nroots'].value
        wfnsym = fh5['mc/wfnsym'].value
        fh5.close()
    else:
        mol = mc.mol
        ncas = mc.ncas
        ncore = mc.ncore
        nvirt = mc.mo_coeff.shape[1] - mc.ncas - mc.ncore
        nelecas = mc.nelecas
        nroots = mc.fcisolver.nroots
        wfnsym = mc.fcisolver.wfnsym
        nevpt_integral_file = 'nevpt_perturb_integral'
        write_chk(mc, root, nevpt_integral_file)

    if nevptsolver is None:
        nevptsolver = default_nevpt_schedule(mol, maxM, tol)
        nevptsolver.__dict__.update(mc.fcisolver.__dict__)
        nevptsolver.wfnsym = wfnsym
        nevptsolver.block_extra_keyword = mc.fcisolver.block_extra_keyword
    nevptsolver.nroots = nroots
    nevptsolver.executable = settings.BLOCKEXE_COMPRESS_NEVPT

    conf = dmrgci.writeDMRGConfFile(
        nevptsolver,
        nelecas,
        False,
        with_2pdm=False,
        extraline=['fullrestart', 'nevpt_state_num %d' % root])
    with open(conf, 'r') as f:
        block_conf = f.readlines()
        block_conf = [l for l in block_conf if 'prefix' not in l]
        block_conf = '\n'.join(block_conf)

    with h5py.File(nevpt_integral_file) as fh5:
        if 'dmrg.conf' in fh5:
            del (fh5['dmrg.conf'])
        fh5['dmrg.conf'] = block_conf

    if nevptsolver.verbose >= logger.DEBUG1:
        logger.debug1(nevptsolver, 'Block Input conf')
        logger.debug1(nevptsolver, block_conf)

    t0 = (time.clock(), time.time())

    cmd = ' '.join(
        (nevptsolver.mpiprefix,
         os.path.realpath(os.path.join(__file__, '..', 'nevpt_mpi.py')),
         nevpt_integral_file, nevptsolver.executable,
         mc.fcisolver.scratchDirectory, nevptsolver.scratchDirectory))
    logger.debug(nevptsolver, 'DMRG_COMPRESS_NEVPT cmd %s', cmd)

    try:
        output = subprocess.check_call(cmd, shell=True)
    except subprocess.CalledProcessError as err:
        logger.error(nevptsolver, cmd)
        raise err

    if nevptsolver.verbose >= logger.DEBUG1:
        logger.debug1(
            nevptsolver,
            open(os.path.join(nevptsolver.scratchDirectory,
                              '0/dmrg.out')).read())

    fh5 = h5py.File('Perturbation_%d' % root, 'r')
    Vi_e = fh5['Vi/energy'].value
    Vr_e = fh5['Vr/energy'].value
    fh5.close()
    logger.note(nevptsolver, 'Nevpt Energy:')
    logger.note(nevptsolver, 'Sr Subspace:  E = %.14f' % (Vr_e))
    logger.note(nevptsolver, 'Si Subspace:  E = %.14f' % (Vi_e))

    logger.timer(nevptsolver, 'MPS NEVPT calculation time', *t0)
コード例 #25
0
ファイル: rintermediates.py プロジェクト: wmizukami/pyscf
def get_t3p2_imds_slow(cc,
                       t1,
                       t2,
                       eris=None,
                       t3p2_ip_out=None,
                       t3p2_ea_out=None):
    """Calculates T1, T2 amplitudes corrected by second-order T3 contribution
    and intermediates used in IP/EA-CCSD(T)a

    For description of arguments, see `get_t3p2_imds_slow` in `gintermediates.py`.
    """
    if eris is None:
        eris = cc.ao2mo()
    fock = eris.fock
    nocc, nvir = t1.shape

    fov = fock[:nocc, nocc:]
    foo = fock[:nocc, :nocc].diagonal()
    fvv = fock[nocc:, nocc:].diagonal()

    fov = fock[:nocc, nocc:]
    foo = fock[:nocc, :nocc].diagonal()
    fvv = fock[nocc:, nocc:].diagonal()
    dtype = np.result_type(t1, t2)
    if np.issubdtype(dtype, np.dtype(complex).type):
        logger.error(
            cc,
            't3p2 imds has not been strictly checked for use with complex integrals'
        )

    mo_e_o = eris.mo_energy[:nocc]
    mo_e_v = eris.mo_energy[nocc:]

    ovov = _cp(eris.ovov)
    ovvv = _cp(eris.get_ovvv())
    eris_vvov = eris.get_ovvv().conj().transpose(1, 3, 0,
                                                 2)  # Physicist notation
    eris_vooo = eris.ovoo[:].conj().transpose(1, 0, 3, 2)  # Chemist notation

    ccsd_energy = cc.energy(t1, t2, eris)
    dtype = np.result_type(t1, t2)

    if t3p2_ip_out is None:
        t3p2_ip_out = np.zeros((nocc, nvir, nocc, nocc), dtype=dtype)
    Wmbkj = t3p2_ip_out

    if t3p2_ea_out is None:
        t3p2_ea_out = np.zeros((nvir, nvir, nvir, nocc), dtype=dtype)
    Wcbej = t3p2_ea_out

    tmp_t3 = np.einsum('abif,kjcf->ijkabc', eris_vvov, t2)
    tmp_t3 -= np.einsum('aimj,mkbc->ijkabc', eris_vooo, t2)

    tmp_t3 = (tmp_t3 + tmp_t3.transpose(0, 2, 1, 3, 5, 4) +
              tmp_t3.transpose(1, 0, 2, 4, 3, 5) +
              tmp_t3.transpose(1, 2, 0, 4, 5, 3) +
              tmp_t3.transpose(2, 0, 1, 5, 3, 4) +
              tmp_t3.transpose(2, 1, 0, 5, 4, 3))

    eia = mo_e_o[:, None] - mo_e_v[None, :]
    eijab = eia[:, None, :, None] + eia[None, :, None, :]
    eijkabc = eijab[:, :, None, :, :, None] + eia[None, None, :, None, None, :]
    tmp_t3 /= eijkabc

    Ptmp_t3 = 2. * tmp_t3 - tmp_t3.transpose(
        1, 0, 2, 3, 4, 5) - tmp_t3.transpose(2, 1, 0, 3, 4, 5)
    pt1 = 0.5 * lib.einsum('jbkc,ijkabc->ia',
                           2. * ovov - ovov.transpose(0, 3, 2, 1), Ptmp_t3)

    tmp = 0.5 * lib.einsum('ijkabc,ia->jkbc', Ptmp_t3, fov)
    pt2 = tmp + tmp.transpose(1, 0, 3, 2)

    #     b\    / \    /
    #  /\---\  /   \  /
    # i\/a  d\/j   k\/c
    # ------------------
    tmp = lib.einsum('ijkabc,iadb->jkdc', Ptmp_t3, ovvv)
    pt2 += (tmp + tmp.transpose(1, 0, 3, 2))

    #     m\    / \    /
    #  /\---\  /   \  /
    # i\/a  j\/b   k\/c
    # ------------------
    tmp = lib.einsum('ijkabc,iajm->mkbc', Ptmp_t3, eris.ovoo)
    pt2 -= (tmp + tmp.transpose(1, 0, 3, 2))

    eia = mo_e_o[:, None] - mo_e_v[None, :]
    eijab = eia[:, None, :, None] + eia[None, :, None, :]

    pt1 /= eia
    pt2 /= eijab

    pt1 += t1
    pt2 += t2

    Wmbkj += lib.einsum('ijkabc,mcia->mbkj', Ptmp_t3, ovov)

    Wcbej += -1.0 * lib.einsum('ijkabc,iake->cbej', Ptmp_t3, ovov)

    delta_ccsd_energy = cc.energy(pt1, pt2, eris) - ccsd_energy
    logger.info(cc, 'CCSD energy T3[2] correction : %14.8e', delta_ccsd_energy)
    return delta_ccsd_energy, pt1, pt2, Wmbkj, Wcbej
コード例 #26
0
ファイル: nevpt2.py プロジェクト: raybrad/pyscf
def sc_nevpt(mc, ci=None, useMPS=False, verbose=None):
    """Strongly contracted NEVPT2"""
    if ci is None:
        ci = mc.ci
    # mc.cas_natorb(ci=ci)

    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(mc.stdout, mc.verbose)

    time0 = (time.clock(), time.time())

    # By defaut, mc is canonicalized for the first root.
    if mc.fcisolver.nroots > 1:
        mc.mo_coeff, _, mc.mo_energy = mc.canonicalize(mc.mo_coeff, ci=ci, verbose=log)

    # if not useMPS:
    #    mc.mo_coeff, _, orbe = mc.canonicalize(casdm1=dm1)
    # else:
    #    orbe = reduce(numpy.dot, (mc.mo_coeff.T, mc.get_fock(ci=ci), mc.mo_coeff)).diagonal()

    if hasattr(mc.fcisolver, "nevpt_intermediate"):
        logger.info(mc, "DMRG-NEVPT")
        dm1, dm2, dm3 = mc.fcisolver.make_rdm123(ci, mc.ncas, mc.nelecas, None)
    else:
        if useMPS:
            logger.error(mc, "MPS nevpt only used for DMRG calculation")
            exit()
        dm1, dm2, dm3 = fci.rdm.make_dm123("FCI3pdm_kern_sf", ci, ci, mc.ncas, mc.nelecas)
    dm4 = None

    dms = {
        "1": dm1,
        "2": dm2,
        "3": dm3,
        "4": dm4,
        #'h1': hdm1, 'h2': hdm2, 'h3': hdm3
    }
    time1 = log.timer("3pdm, 4pdm", *time0)

    eris = _ERIS(mc, mc.mo_coeff)
    time1 = log.timer("integral transformation", *time1)
    nocc = mc.ncore + mc.ncas

    if not hasattr(mc.fcisolver, "nevpt_intermediate"):  # regular FCI solver
        link_indexa = fci.cistring.gen_linkstr_index(range(mc.ncas), mc.nelecas[0])
        link_indexb = fci.cistring.gen_linkstr_index(range(mc.ncas), mc.nelecas[1])
        aaaa = eris["ppaa"][mc.ncore : nocc, mc.ncore : nocc].copy()
        f3ca = _contract4pdm("NEVPTkern_cedf_aedf", aaaa, ci, mc.ncas, mc.nelecas, (link_indexa, link_indexb))
        f3ac = _contract4pdm("NEVPTkern_aedf_ecdf", aaaa, ci, mc.ncas, mc.nelecas, (link_indexa, link_indexb))
        dms["f3ca"] = f3ca
        dms["f3ac"] = f3ac
    time1 = log.timer("eri-4pdm contraction", *time1)

    if useMPS:
        fh5 = h5py.File("Perturbation_%d" % ci, "r")
        e_Si = fh5["Vi/energy"].value
        norm_Si = fh5["Vi/norm"].value
        e_Sr = fh5["Vr/energy"].value
        norm_Sr = fh5["Vr/norm"].value
        fh5.close()
        logger.note(mc, "Sr    (-1)', Norm = %.14f  E = %.14f", norm_Sr, e_Sr)
        logger.note(mc, "Si    (+1)', Norm = %.14f  E = %.14f", norm_Si, e_Si)

    else:
        norm_Sr, e_Sr = Sr(mc, ci, dms, eris)
        logger.note(mc, "Sr    (-1)', Norm = %.14f  E = %.14f", norm_Sr, e_Sr)
        time1 = log.timer("space Sr (-1)'", *time1)
        norm_Si, e_Si = Si(mc, ci, dms, eris)
        logger.note(mc, "Si    (+1)', Norm = %.14f  E = %.14f", norm_Si, e_Si)
        time1 = log.timer("space Si (+1)'", *time1)
    norm_Sijrs, e_Sijrs = Sijrs(mc, eris)
    logger.note(mc, "Sijrs (0)  , Norm = %.14f  E = %.14f", norm_Sijrs, e_Sijrs)
    time1 = log.timer("space Sijrs (0)", *time1)
    norm_Sijr, e_Sijr = Sijr(mc, dms, eris)
    logger.note(mc, "Sijr  (+1) , Norm = %.14f  E = %.14f", norm_Sijr, e_Sijr)
    time1 = log.timer("space Sijr (+1)", *time1)
    norm_Srsi, e_Srsi = Srsi(mc, dms, eris)
    logger.note(mc, "Srsi  (-1) , Norm = %.14f  E = %.14f", norm_Srsi, e_Srsi)
    time1 = log.timer("space Srsi (-1)", *time1)
    norm_Srs, e_Srs = Srs(mc, dms, eris)
    logger.note(mc, "Srs   (-2) , Norm = %.14f  E = %.14f", norm_Srs, e_Srs)
    time1 = log.timer("space Srs (-2)", *time1)
    norm_Sij, e_Sij = Sij(mc, dms, eris)
    logger.note(mc, "Sij   (+2) , Norm = %.14f  E = %.14f", norm_Sij, e_Sij)
    time1 = log.timer("space Sij (+2)", *time1)
    norm_Sir, e_Sir = Sir(mc, dms, eris)
    logger.note(mc, "Sir   (0)' , Norm = %.14f  E = %.14f", norm_Sir, e_Sir)
    time1 = log.timer("space Sir (0)'", *time1)

    nevpt_e = e_Sr + e_Si + e_Sijrs + e_Sijr + e_Srsi + e_Srs + e_Sij + e_Sir
    logger.note(mc, "Nevpt2 Energy = %.15f", nevpt_e)
    log.timer("SC-NEVPT2", *time0)
    return nevpt_e
コード例 #27
0
def mo_k2gamma(cell,
               mo_energy,
               mo_coeff,
               kpts,
               kmesh=None,
               degen_tol=1e-3,
               imag_tol=1e-9):
    logger.debug(cell, "Starting mo_k2gamma")
    scell, phase = get_phase(cell, kpts, kmesh)

    # Supercell Gamma-point MO energies
    e_gamma = np.hstack(mo_energy)
    # The number of MOs may be k-point dependent (eg. due to linear dependency)
    nmo_k = np.asarray([ck.shape[-1] for ck in mo_coeff])
    nk = len(mo_coeff)
    nao = mo_coeff[0].shape[0]
    nr = phase.shape[0]
    # Transform mo_coeff from k-points to supercell Gamma-point:
    c_gamma = []
    for k in range(nk):
        c_k = np.einsum('R,um->Rum', phase[:, k], mo_coeff[k])
        c_k = c_k.reshape(nr * nao, nmo_k[k])
        c_gamma.append(c_k)
    c_gamma = np.hstack(c_gamma)
    assert c_gamma.shape == (nr * nao, sum(nmo_k))
    # Sort according to MO energy
    sort = np.argsort(e_gamma)
    e_gamma, c_gamma = e_gamma[sort], c_gamma[:, sort]
    # Determine overlap by unfolding for better accuracy
    s_k = cell.pbc_intor('int1e_ovlp',
                         hermi=1,
                         kpts=kpts,
                         pbcopt=lib.c_null_ptr())
    s_gamma = to_supercell_ao_integrals(cell, kpts, s_k)
    # Orthogonality error of unfolded MOs
    err_orth = abs(
        np.linalg.multi_dot((c_gamma.conj().T, s_gamma, c_gamma)) -
        np.eye(c_gamma.shape[-1])).max()
    if err_orth > 1e-4:
        logger.error(cell, "Orthogonality error of MOs= %.2e !!!", err_orth)
    else:
        logger.debug(cell, "Orthogonality error of MOs= %.2e", err_orth)

    # Make Gamma point MOs real:

    # Try to remove imaginary parts by multiplication of simple phase factors
    c_gamma = rotate_mo_to_real(cell, e_gamma, c_gamma, degen_tol=degen_tol)

    # For degenerated MOs, the transformed orbitals in super cell may not be
    # real. Construct a sub Fock matrix in super-cell to find a proper
    # transformation that makes the transformed MOs real.
    #e_k_degen = abs(e_gamma[1:] - e_gamma[:-1]) < degen_tol
    #degen_mask = np.append(False, e_k_degen) | np.append(e_k_degen, False)

    # Get eigenvalue solver with linear-dependency treatment
    eigh = cell.eigh_factory(lindep_threshold=1e-13, fallback_mode=True)

    c_gamma_out = c_gamma.copy()
    mo_mask = (np.linalg.norm(c_gamma.imag, axis=0) > imag_tol)
    logger.debug(cell,
                 "Number of MOs with imaginary coefficients: %d out of %d",
                 np.count_nonzero(mo_mask), len(mo_mask))
    if np.any(mo_mask):
        #mo_mask = np.s_[:]
        #if np.any(~degen_mask):
        #    err_imag = abs(c_gamma[:,~degen_mask].imag).max()
        #    logger.debug(cell, "Imaginary part in non-degenerate MO coefficients= %.2e", err_imag)
        #    # Diagonalize Fock matrix spanned by degenerate MOs only
        #    if err_imag < 1e-8:
        #        mo_mask = degen_mask

        # F
        #mo_mask = (np.linalg.norm(c_gamma.imag, axis=0) > imag_tol)

        # Shift all MOs above the eig=0 subspace, so they can be extracted below
        shift = 1.0 - min(e_gamma[mo_mask])
        cs = np.dot(c_gamma[:, mo_mask].conj().T, s_gamma)
        f_gamma = np.dot(cs.T.conj() * (e_gamma[mo_mask] + shift), cs)
        logger.debug(
            cell,
            "Imaginary parts of Fock matrix: ||Im(F)||= %.2e  max|Im(F)|= %.2e",
            np.linalg.norm(f_gamma.imag),
            abs(f_gamma.imag).max())

        e, v = eigh(f_gamma.real, s_gamma)

        # Extract MOs from rank-deficient Fock matrix
        mask = (e > 0.5)
        assert np.count_nonzero(mask) == len(e_gamma[mo_mask])
        e, v = e[mask], v[:, mask]
        e_delta = e_gamma[mo_mask] - (e - shift)
        if abs(e_delta).max() > 1e-4:
            logger.error(
                cell, "Error of MO energies: ||dE||= %.2e  max|dE|= %.2e !!!",
                np.linalg.norm(e_delta),
                abs(e_delta).max())
        else:
            logger.debug(cell,
                         "Error of MO energies: ||dE||= %.2e  max|dE|= %.2e",
                         np.linalg.norm(e_delta),
                         abs(e_delta).max())
        c_gamma_out[:, mo_mask] = v

    err_imag = abs(c_gamma_out.imag).max()
    if err_imag > 1e-4:
        logger.error(
            cell, "Imaginary part in gamma-point MOs: max|Im(C)|= %7.2e !!!",
            err_imag)
    else:
        logger.debug(cell,
                     "Imaginary part in gamma-point MOs: max|Im(C)|= %7.2e",
                     err_imag)
    c_gamma_out = c_gamma_out.real

    # Determine mo_phase, i.e. the unitary transformation from k-adapted orbitals to gamma-point orbitals
    s_k_g = np.einsum('kuv,Rk->kuRv', s_k,
                      phase.conj()).reshape(nk, nao, nr * nao)
    mo_phase = []
    for k in range(nk):
        mo_phase_k = lib.einsum('um,uv,vi->mi', mo_coeff[k].conj(), s_k_g[k],
                                c_gamma_out)
        mo_phase.append(mo_phase_k)

    return scell, e_gamma, c_gamma_out, mo_phase
コード例 #28
0
ファイル: nevpt2.py プロジェクト: Bismarrck/pyscf
def sc_nevpt(mc, ci=None, useMPS=False, verbose=None):
    '''Strongly contracted NEVPT2'''
    if ci is None:
        ci=mc.ci
    #mc.cas_natorb(ci=ci)

    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(mc.stdout, mc.verbose)

    time0 = (time.clock(), time.time())
    #dm1, dm2, dm3, dm4 = fci.rdm.make_dm1234('FCI4pdm_kern_sf',
    #                                         mc.ci, mc.ci, mc.ncas, mc.nelecas)
    logger.debug(mc, 'mc.fcisolver = %s', type(mc.fcisolver))

    if hasattr(mc.fcisolver, 'nevpt_intermediate'):
        logger.info(mc, 'DMRG-NEVPT')
        dm1, dm2, dm3 = mc.fcisolver.make_rdm123(ci,mc.ncas,mc.nelecas,None)
    else:
        if useMPS:
            logger.error(mc,"MPS nevpt only used for DMRG calculation")
            exit()
        dm1, dm2, dm3 = fci.rdm.make_dm123('FCI3pdm_kern_sf',
                                           ci, ci, mc.ncas, mc.nelecas)
    dm4 = None
    if not useMPS:
        mc.mo_coeff, _, orbe = mc.canonicalize(casdm1=dm1)
    else:
        orbe = reduce(numpy.dot, (mc.mo_coeff.T, mc.get_fock(), mc.mo_coeff)).diagonal()


    #hdm1 = make_hdm1(dm1)
    #hdm2 = make_hdm2(dm1,dm2)
    #hdm3 = make_hdm3(dm1,dm2,dm3,hdm1,hdm2)

    dms = {'1': dm1, '2': dm2, '3': dm3, '4': dm4,
           #'h1': hdm1, 'h2': hdm2, 'h3': hdm3
          }
    time1 = log.timer('3pdm, 4pdm', *time0)

    eris = _ERIS(mc, mc.mo_coeff)
    time1 = log.timer('integral transformation', *time1)
    nocc = mc.ncore + mc.ncas



    if not hasattr(mc.fcisolver, 'nevpt_intermediate'):  # regular FCI solver
        link_indexa = fci.cistring.gen_linkstr_index(range(mc.ncas), mc.nelecas[0])
        link_indexb = fci.cistring.gen_linkstr_index(range(mc.ncas), mc.nelecas[1])
        aaaa = eris['ppaa'][mc.ncore:nocc,mc.ncore:nocc].copy()
        f3ca = _contract4pdm('NEVPTkern_cedf_aedf', aaaa, ci, mc.ncas,
                             mc.nelecas, (link_indexa,link_indexb))
        f3ac = _contract4pdm('NEVPTkern_aedf_ecdf', aaaa, ci, mc.ncas,
                             mc.nelecas, (link_indexa,link_indexb))
        dms['f3ca'] = f3ca
        dms['f3ac'] = f3ac
    time1 = log.timer('eri-4pdm contraction', *time1)

    if useMPS:
        fh5 = h5py.File('Perturbation_%d'%ci,'r')
        e_Si     =   fh5['Vi/energy'].value    
        norm_Si  =   fh5['Vi/norm'].value       
        e_Sr     =   fh5['Vr/energy'].value     
        norm_Sr  =   fh5['Vr/norm'].value       
        fh5.close()
        logger.note(mc, "Sr    (-1)', Norm = %.14f  E = %.14f", norm_Sr  , e_Sr  )
        logger.note(mc, "Si    (+1)', Norm = %.14f  E = %.14f", norm_Si  , e_Si  )

    else:
        norm_Sr   , e_Sr    = Sr(mc,ci,orbe, dms, eris)
        logger.note(mc, "Sr    (-1)', Norm = %.14f  E = %.14f", norm_Sr  , e_Sr  )
        time1 = log.timer("space Sr (-1)'", *time1)
        norm_Si   , e_Si    = Si(mc,ci,orbe, dms, eris)
        logger.note(mc, "Si    (+1)', Norm = %.14f  E = %.14f", norm_Si  , e_Si  )
        time1 = log.timer("space Si (+1)'", *time1)
    norm_Sijrs, e_Sijrs = Sijrs(mc,orbe, eris)
    logger.note(mc, "Sijrs (0)  , Norm = %.14f  E = %.14f", norm_Sijrs,e_Sijrs)
    time1 = log.timer('space Sijrs (0)', *time1)
    norm_Sijr , e_Sijr  = Sijr(mc,orbe, dms, eris)
    logger.note(mc, "Sijr  (+1) , Norm = %.14f  E = %.14f", norm_Sijr, e_Sijr)
    time1 = log.timer('space Sijr (+1)', *time1)
    norm_Srsi , e_Srsi  = Srsi(mc,orbe, dms, eris)
    logger.note(mc, "Srsi  (-1) , Norm = %.14f  E = %.14f", norm_Srsi, e_Srsi)
    time1 = log.timer('space Srsi (-1)', *time1)
    norm_Srs  , e_Srs   = Srs(mc,orbe, dms, eris)
    logger.note(mc, "Srs   (-2) , Norm = %.14f  E = %.14f", norm_Srs , e_Srs )
    time1 = log.timer('space Srs (-2)', *time1)
    norm_Sij  , e_Sij   = Sij(mc,orbe, dms, eris)
    logger.note(mc, "Sij   (+2) , Norm = %.14f  E = %.14f", norm_Sij , e_Sij )
    time1 = log.timer('space Sij (+2)', *time1)
    norm_Sir  , e_Sir   = Sir(mc,orbe, dms, eris)
    logger.note(mc, "Sir   (0)' , Norm = %.14f  E = %.14f", norm_Sir , e_Sir )
    time1 = log.timer("space Sir (0)'", *time1)

    nevpt_e  = e_Sr + e_Si + e_Sijrs + e_Sijr + e_Srsi + e_Srs + e_Sij + e_Sir
    logger.note(mc, "Nevpt2 Energy = %.15f", nevpt_e)
    log.timer('SC-NEVPT2', *time0)
    return nevpt_e
コード例 #29
0
ファイル: gintermediates.py プロジェクト: zzy2014/pyscf
def get_t3p2_imds_slow(cc,
                       t1,
                       t2,
                       eris=None,
                       t3p2_ip_out=None,
                       t3p2_ea_out=None):
    """Calculates T1, T2 amplitudes corrected by second-order T3 contribution
    and intermediates used in IP/EA-CCSD(T)a

    Args:
        cc (:obj:`GCCSD`):
            Object containing coupled-cluster results.
        t1 (:obj:`ndarray`):
            T1 amplitudes.
        t2 (:obj:`ndarray`):
            T2 amplitudes from which the T3[2] amplitudes are formed.
        eris (:obj:`_PhysicistsERIs`):
            Antisymmetrized electron-repulsion integrals in physicist's notation.
        t3p2_ip_out (:obj:`ndarray`):
            Store results of the intermediate used in IP-EOM-CCSD(T)a.
        t3p2_ea_out (:obj:`ndarray`):
            Store results of the intermediate used in EA-EOM-CCSD(T)a.

    Returns:
        delta_ccsd (float):
            Difference of perturbed and unperturbed CCSD ground-state energy,
                energy(T1 + T1[2], T2 + T2[2]) - energy(T1, T2)
        pt1 (:obj:`ndarray`):
            Perturbatively corrected T1 amplitudes.
        pt2 (:obj:`ndarray`):
            Perturbatively corrected T2 amplitudes.

    Reference:
        D. A. Matthews, J. F. Stanton "A new approach to approximate..."
            JCP 145, 124102 (2016); DOI:10.1063/1.4962910, Equation 14
        Shavitt and Bartlett "Many-body Methods in Physics and Chemistry"
            2009, Equation 10.33
    """
    if eris is None:
        eris = cc.ao2mo()
    fock = eris.fock
    nocc, nvir = t1.shape

    fov = fock[:nocc, nocc:]
    #foo = fock[:nocc, :nocc].diagonal()
    #fvv = fock[nocc:, nocc:].diagonal()

    mo_e_o = eris.mo_energy[:nocc]
    mo_e_v = eris.mo_energy[nocc:]

    oovv = _cp(eris.oovv)
    ovvv = _cp(eris.ovvv)
    ooov = _cp(eris.ooov)
    oovv = _cp(eris.oovv)
    vooo = _cp(ooov).conj().transpose(3, 2, 1, 0)
    vvvo = _cp(ovvv).conj().transpose(3, 2, 1, 0)

    ccsd_energy = cc.energy(t1, t2, eris)
    dtype = np.result_type(t1, t2)
    if np.issubdtype(dtype, np.dtype(complex).type):
        logger.error(
            cc,
            't3p2 imds has not been strictly checked for use with complex integrals'
        )

    if t3p2_ip_out is None:
        t3p2_ip_out = np.zeros((nocc, nvir, nocc, nocc), dtype=dtype)
    Wmcik = t3p2_ip_out

    if t3p2_ea_out is None:
        t3p2_ea_out = np.zeros((nvir, nvir, nvir, nocc), dtype=dtype)
    Wacek = t3p2_ea_out

    tmp_t3 = lib.einsum('bcdk,ijad->ijkabc', vvvo, t2)
    tmp_t3 -= lib.einsum('cmkj,imab->ijkabc', vooo, t2)

    # P(ijk)
    tmp_t3 = (tmp_t3 + tmp_t3.transpose(1, 2, 0, 3, 4, 5) +
              tmp_t3.transpose(2, 0, 1, 3, 4, 5))
    # P(abc)
    tmp_t3 = (tmp_t3 + tmp_t3.transpose(0, 1, 2, 4, 5, 3) +
              tmp_t3.transpose(0, 1, 2, 5, 3, 4))

    eia = mo_e_o[:, None] - mo_e_v[None, :]
    eijab = eia[:, None, :, None] + eia[None, :, None, :]
    eijkabc = eijab[:, :, None, :, :, None] + eia[None, None, :, None, None, :]
    tmp_t3 /= eijkabc

    pt1 = 0.25 * lib.einsum('mnef,imnaef->ia', oovv, tmp_t3)

    pt2 = lib.einsum('ijmabe,me->ijab', tmp_t3, fov)
    tmp2 = ovvv - 0.0 * lib.einsum('nmef,nb->mbfe', oovv, t1)
    tmp = lib.einsum('ijmaef,mbfe->ijab', tmp_t3, tmp2)
    tmp = tmp - tmp.transpose(0, 1, 3, 2)  # P(ab)
    tmp *= 0.5
    pt2 = pt2 + tmp
    tmp2 = ooov + 0.0 * lib.einsum('mnef,jf->nmje', oovv, t1)
    tmp = lib.einsum('inmabe,nmje->ijab', tmp_t3, tmp2)
    tmp *= -0.5
    tmp = tmp - tmp.transpose(1, 0, 2, 3)  # P(ij)
    pt2 = pt2 + tmp

    eia = mo_e_o[:, None] - mo_e_v[None, :]
    eijab = eia[:, None, :, None] + eia[None, :, None, :]

    pt1 /= eia
    pt2 /= eijab

    pt1 = pt1 + t1
    pt2 = pt2 + t2

    Wmcik += 0.5 * lib.einsum('ijkabc,mjab->mcik', tmp_t3, oovv)
    Wacek += -0.5 * lib.einsum('ijkabc,ijeb->acek', tmp_t3, oovv)

    delta_ccsd_energy = cc.energy(pt1, pt2, eris) - ccsd_energy
    logger.info(cc, 'CCSD energy T3[2] correction : %16.12e',
                delta_ccsd_energy)
    return delta_ccsd_energy, pt1, pt2, Wmcik, Wacek
コード例 #30
0
ファイル: addons.py プロジェクト: pengdl/pyscf
def label_orb_symm(mol, irrep_name, symm_orb, mo, s=None, check=True):
    '''Label the symmetry of given orbitals

    irrep_name can be either the symbol or the ID of the irreducible
    representation.  If the ID is provided, it returns the numeric code
    associated with XOR operator, see :py:meth:`symm.param.IRREP_ID_TABLE`

    Args:
        mol : an instance of :class:`Mole`

        irrep_name : list of str or int
            A list of irrep ID or name,  it can be either mol.irrep_id or
            mol.irrep_name.  It can affect the return "label".
        symm_orb : list of 2d array
            the symmetry adapted basis
        mo : 2d array
            the orbitals to label

    Returns:
        list of symbols or integers to represent the irreps for the given
        orbitals

    Examples:

    >>> from pyscf import gto, scf, symm
    >>> mol = gto.M(atom='H 0 0 0; H 0 0 1', basis='ccpvdz',verbose=0, symmetry=1)
    >>> mf = scf.RHF(mol)
    >>> mf.kernel()
    >>> symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mf.mo_coeff)
    ['Ag', 'B1u', 'Ag', 'B1u', 'B2u', 'B3u', 'Ag', 'B2g', 'B3g', 'B1u']
    >>> symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mf.mo_coeff)
    [0, 5, 0, 5, 6, 7, 0, 2, 3, 5]
    '''
    nmo = mo.shape[1]
    if s is None:
        s = mol.intor_symmetric('cint1e_ovlp_sph')
    mo_s = numpy.dot(mo.T, s)
    norm = numpy.empty((len(irrep_name), nmo))
    for i,ir in enumerate(irrep_name):
        moso = numpy.dot(mo_s, symm_orb[i])
        norm[i] = numpy.einsum('ij,ij->i', moso, moso)
    iridx = numpy.argmax(norm, axis=0)
    orbsym = [irrep_name[i] for i in iridx]
    logger.debug(mol, 'irreps of each MO %s', str(orbsym))
    if check:
        norm[iridx,numpy.arange(nmo)] = 0
        orbidx = numpy.where(norm > THRESHOLD)
        if orbidx[1].size > 0:
            idx = numpy.where(norm > THRESHOLD*1e2)
            if idx[1].size > 0:
                logger.error(mol, 'orbitals %s not symmetrized, norm = %s',
                             idx[1], norm[idx])
                raise ValueError('orbitals %s not symmetrized' %
                                 numpy.unique(idx[1]))
            else:
                logger.warn(mol, 'orbitals %s not strictly symmetrized.',
                            numpy.unique(orbidx[1]))
                logger.warn(mol, 'They can be symmetrized with '
                            'pyscf.symm.symmetrize_orb function.')
                logger.debug(mol, 'norm = %s', norm[orbidx])
    return orbsym
コード例 #31
0
ファイル: nevpt_mpi.py プロジェクト: wmizukami/pyscf
def DMRG_COMPRESS_NEVPT(mc,
                        maxM=500,
                        root=0,
                        nevptsolver=None,
                        tol=1e-7,
                        nevpt_integral=None):

    if isinstance(nevpt_integral, str) and h5py.is_hdf5(nevpt_integral):
        nevpt_integral_file = os.path.abspath(nevpt_integral)
        mol = chkfile.load_mol(nevpt_integral_file)

        fh5 = h5py.File(nevpt_integral_file, 'r')
        ncas = fh5['mc/ncas'][()]
        ncore = fh5['mc/ncore'][()]
        nvirt = fh5['mc/nvirt'][()]
        nelecas = fh5['mc/nelecas'][()]
        nroots = fh5['mc/nroots'][()]
        wfnsym = fh5['mc/wfnsym'][()]
        fh5.close()
    else:
        mol = mc.mol
        ncas = mc.ncas
        ncore = mc.ncore
        nvirt = mc.mo_coeff.shape[1] - mc.ncas - mc.ncore
        nelecas = mc.nelecas
        nroots = mc.fcisolver.nroots
        wfnsym = mc.fcisolver.wfnsym
        nevpt_integral_file = None

    if nevptsolver is None:
        nevptsolver = default_nevpt_schedule(mc.fcisolver, maxM, tol)
        #nevptsolver.__dict__.update(mc.fcisolver.__dict__)
        nevptsolver.wfnsym = wfnsym
        nevptsolver.block_extra_keyword = mc.fcisolver.block_extra_keyword
    nevptsolver.nroots = nroots
    nevptsolver.executable = settings.BLOCKEXE_COMPRESS_NEVPT
    if nevptsolver.executable == getattr(mc.fcisolver, 'executable', None):
        logger.warn(
            mc, 'DMRG executable file for nevptsolver is the same '
            'to the executable file for DMRG solver. If they are '
            'both compiled by MPI compilers, they may cause error or '
            'random results in DMRG-NEVPT calculation.')

    nevpt_scratch = os.path.abspath(nevptsolver.scratchDirectory)
    dmrg_scratch = os.path.abspath(mc.fcisolver.scratchDirectory)

    # Integrals are not given by the kwarg nevpt_integral
    if nevpt_integral_file is None:
        nevpt_integral_file = os.path.join(nevpt_scratch,
                                           'nevpt_perturb_integral')
        write_chk(mc, root, nevpt_integral_file)

    conf = dmrgci.writeDMRGConfFile(
        nevptsolver,
        nelecas,
        False,
        with_2pdm=False,
        extraline=['fullrestart', 'nevpt_state_num %d' % root])
    with open(conf, 'r') as f:
        block_conf = f.readlines()
        block_conf = [l for l in block_conf if 'prefix' not in l]
        block_conf = ''.join(block_conf)

    with h5py.File(nevpt_integral_file, 'a') as fh5:
        if 'dmrg.conf' in fh5:
            del (fh5['dmrg.conf'])
        fh5['dmrg.conf'] = block_conf

    if nevptsolver.verbose >= logger.DEBUG1:
        logger.debug1(nevptsolver, 'Block Input conf')
        logger.debug1(nevptsolver, block_conf)

    t0 = (time.clock(), time.time())

    # function nevpt_integral_mpi is called in this cmd
    cmd = ' '.join(
        (nevptsolver.mpiprefix,
         os.path.realpath(os.path.join(__file__, '..',
                                       'nevpt_mpi.py')), nevpt_integral_file,
         nevptsolver.executable, dmrg_scratch, nevpt_scratch))
    logger.debug(nevptsolver, 'DMRG_COMPRESS_NEVPT cmd %s', cmd)

    try:
        output = subprocess.check_call(cmd, shell=True)
    except subprocess.CalledProcessError as err:
        logger.error(nevptsolver, cmd)
        raise err

    if nevptsolver.verbose >= logger.DEBUG1:
        logger.debug1(
            nevptsolver,
            open(os.path.join(nevpt_scratch, '0', 'dmrg.out')).read())

    perturb_file = os.path.join(nevpt_scratch, '0', 'Perturbation_%d' % root)
    fh5 = h5py.File(perturb_file, 'r')
    Vi_e = fh5['Vi/energy'][()]
    Vr_e = fh5['Vr/energy'][()]
    fh5.close()
    logger.note(nevptsolver, 'Nevpt Energy:')
    logger.note(nevptsolver, 'Sr Subspace:  E = %.14f' % (Vr_e))
    logger.note(nevptsolver, 'Si Subspace:  E = %.14f' % (Vi_e))

    logger.timer(nevptsolver, 'MPS NEVPT calculation time', *t0)
    return perturb_file
コード例 #32
0
ファイル: nevpt2.py プロジェクト: matk86/pyscf
def sc_nevpt(mc, ci=None, useMPS=False, verbose=None):
    '''Strongly contracted NEVPT2'''
    if ci is None:
        ci=mc.ci
    #mc.cas_natorb(ci=ci)

    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(mc.stdout, mc.verbose)

    time0 = (time.clock(), time.time())

    #By defaut, mc is canonicalized for the first root.
    #For SC-NEVPT based on compressed MPS perturber functions, the mc was already canonicalized.
    if mc.fcisolver.nroots > 1 and not useMPS:
        mc.mo_coeff,_, mc.mo_energy = mc.canonicalize(mc.mo_coeff,ci=ci,verbose=log)


    if hasattr(mc.fcisolver, 'nevpt_intermediate'):
        logger.info(mc, 'DMRG-NEVPT')
        dm1, dm2, dm3 = mc.fcisolver.make_rdm123(ci,mc.ncas,mc.nelecas,None)
    else:
        if useMPS:
            logger.error(mc,"MPS nevpt only used for DMRG calculation")
            exit()
        dm1, dm2, dm3 = fci.rdm.make_dm123('FCI3pdm_kern_sf',
                                           ci, ci, mc.ncas, mc.nelecas)
    dm4 = None

    dms = {'1': dm1, '2': dm2, '3': dm3, '4': dm4,
           #'h1': hdm1, 'h2': hdm2, 'h3': hdm3
          }
    time1 = log.timer('3pdm, 4pdm', *time0)

    eris = _ERIS(mc, mc.mo_coeff)
    time1 = log.timer('integral transformation', *time1)
    nocc = mc.ncore + mc.ncas



    if not hasattr(mc.fcisolver, 'nevpt_intermediate'):  # regular FCI solver
        link_indexa = fci.cistring.gen_linkstr_index(range(mc.ncas), mc.nelecas[0])
        link_indexb = fci.cistring.gen_linkstr_index(range(mc.ncas), mc.nelecas[1])
        aaaa = eris['ppaa'][mc.ncore:nocc,mc.ncore:nocc].copy()
        f3ca = _contract4pdm('NEVPTkern_cedf_aedf', aaaa, ci, mc.ncas,
                             mc.nelecas, (link_indexa,link_indexb))
        f3ac = _contract4pdm('NEVPTkern_aedf_ecdf', aaaa, ci, mc.ncas,
                             mc.nelecas, (link_indexa,link_indexb))
        dms['f3ca'] = f3ca
        dms['f3ac'] = f3ac
    time1 = log.timer('eri-4pdm contraction', *time1)

    if useMPS:
        fh5 = h5py.File('Perturbation_%d'%ci,'r')
        e_Si     =   fh5['Vi/energy'].value    
        #The definition of norm changed. 
        #However, there is no need to print out it. 
        #Only perturbation energy is wanted.
        norm_Si  =   fh5['Vi/norm'].value       
        e_Sr     =   fh5['Vr/energy'].value     
        norm_Sr  =   fh5['Vr/norm'].value       
        fh5.close()
        logger.note(mc, "Sr    (-1)'  E = %.14f",  e_Sr  )
        logger.note(mc, "Si    (+1)'  E = %.14f",  e_Si  )

    else:
        norm_Sr   , e_Sr    = Sr(mc,ci, dms, eris)
        logger.note(mc, "Sr    (-1)',   E = %.14f",  e_Sr  )
        time1 = log.timer("space Sr (-1)'", *time1)
        norm_Si   , e_Si    = Si(mc,ci, dms, eris)
        logger.note(mc, "Si    (+1)',   E = %.14f",  e_Si  )
        time1 = log.timer("space Si (+1)'", *time1)
    norm_Sijrs, e_Sijrs = Sijrs(mc, eris)
    logger.note(mc, "Sijrs (0)  ,   E = %.14f", e_Sijrs)
    time1 = log.timer('space Sijrs (0)', *time1)
    norm_Sijr , e_Sijr  = Sijr(mc, dms, eris)
    logger.note(mc, "Sijr  (+1) ,   E = %.14f",  e_Sijr)
    time1 = log.timer('space Sijr (+1)', *time1)
    norm_Srsi , e_Srsi  = Srsi(mc, dms, eris)
    logger.note(mc, "Srsi  (-1) ,   E = %.14f",  e_Srsi)
    time1 = log.timer('space Srsi (-1)', *time1)
    norm_Srs  , e_Srs   = Srs(mc, dms, eris)
    logger.note(mc, "Srs   (-2) ,   E = %.14f",  e_Srs )
    time1 = log.timer('space Srs (-2)', *time1)
    norm_Sij  , e_Sij   = Sij(mc, dms, eris)
    logger.note(mc, "Sij   (+2) ,   E = %.14f",  e_Sij )
    time1 = log.timer('space Sij (+2)', *time1)
    norm_Sir  , e_Sir   = Sir(mc, dms, eris)
    logger.note(mc, "Sir   (0)' ,   E = %.14f",  e_Sir )
    time1 = log.timer("space Sir (0)'", *time1)

    nevpt_e  = e_Sr + e_Si + e_Sijrs + e_Sijr + e_Srsi + e_Srs + e_Sij + e_Sir
    logger.note(mc, "Nevpt2 Energy = %.15f", nevpt_e)
    log.timer('SC-NEVPT2', *time0)
    return nevpt_e
コード例 #33
0
    def kernel(self):
        self.get_init()
        sys.exit()
        # rgvb.load_mo(self, in_pre2b+'_gvb.fchk')
        # self.mo_coeff[:,[6,7,8]]=self.mo_coeff[:,[7,8,6]]  # swap orbital
        # self.ci[7,0]=0.998570; self.ci[7,1]=-0.053452
        # self.ci[6,0]=0.981710; self.ci[6,1]=-0.190382
        # self.mol.intor_symmetric('int1e_kin')+mol.intor_symmetric('int1e_nuc')
        hcore = scf.hf.get_hcore(self.mol)
        self.h_mo = reduce(numpy.dot, (self.mo_coeff.T, hcore, self.mo_coeff))
        eri = self.mol.intor('int2e', aosym='s8')
        global i_lowTri; i_lowTri = [0]*self.nobt
        for i in range(1, self.nobt): i_lowTri[i] = i_lowTri[i-1]+i
        from pyscf import ao2mo
        # self.g_mo=ao2mo.outcore.full_iofree(self.mo_coeff[:,:self.nocc+self.npair_d],self.mo_coeff[:,:self.nocc+self.npair_d])
        self.g_mo = ao2mo.kernel(eri, self.mo_coeff)  # s4
        # eri = self.mol.intor('int2e_cart', aosym='s8')
        # eri = self.mol.intor('int2e', aosym='s8')
        # self.g_mo = ao2mo.incore.full(ao2mo.restore(8, eri, self.nbs), self.mo_coeff)

        # check HF energy
        for i in range(self.nocc):
            logger.note(self, '%2d(%6f) <-> %2d(%6f)' % (self.pair[i, 0] + 1, self.ci[i, 0], self.pair[i, 1] + 1, self.ci[i, 1]))
        self.e_ele = self.energy_elec()
        self.e_tot = self.e_ele+self.e_nuc
        logger.note(self, 'e_ele = %10f, e_tot = %.10f' %(self.e_ele,self.e_tot))

        self.opt_ci()
        self.e_tot = self.e_ele + self.e_nuc
        for i in range(self.nocc-self.npair_d,self.nocc):
            logger.note(self, '%2d(%6f) <-> %2d(%6f)' %(self.pair[i,0]+1, self.ci[i,0], self.pair[i,1]+1, self.ci[i,1]))
        logger.note(self, 'e_ele = %10f, e_tot = %.10f' % (self.e_ele, self.e_tot))
        # rgvb.dump_mo(self, '%s_init.fchk' %in_pre2b, reffile)



        logger.note(self, 'start local optimization iteration')
        logger.note(self, '  it       energy         delta')
        logger.note(self, '  it  obt1 orb2       q4           q3           q2           q1         theta       energy       delta(E)        fun        delta(f)')
        for it in range(self.max_cycle[0]):
            _e_ele = self.e_ele
            for u in reversed(range(self.nocc)):
                for i in range(2):
                    if u < self.nocc-self.npair_d and i==1: continue
                    for v in reversed(range(self.nocc-self.npair_d-self.nsig, self.nocc)):
                        for j in range(2):
                            if v < self.nocc - self.npair_d and j == 1: # 注意:单占据的geminal,只能j=0,不能j=1,
                                continue # 因为默认单占据s=0,若j取到1时,也被设置为s=0,而vj=1是core轨道,双占据,就不对了
                            if u==v and i==j: continue
                            b1 = 8*self.ci[u,i]**2 * self.ci[v,j]**2 * (1.-delta(u,v))
                            b2 = (self.s(u)*self.ci[u, i]**2 + self.s(v)*self.ci[v, j]**2
                                       - 2*self.s(u)*self.ci[u, i]*self.ci[v, j]*delta(u, v)
                                       - 2 * self.ci[u, i]**2 * self.ci[v, j]**2 * (2-self.t(u,v)) * (1.-delta(u,v)))
                            auv = (b1*(self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[v,j], self.pair[v,j])]
                                     - self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[u,i], self.pair[v,j])])
                                     +2.*(self.w(u,i,v,j,v,j) - self.w(u,i,u,i,u,i) - self.w(v,j,v,j,v,j) + self.w(v,j,u,i,u,i)))
                            buv = self.w(u,i,u,i,v,j) - self.w(v,j,u,i,v,j)
                            q1 = 4.*buv
                            q2 = auv + 2.*b2*(self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[v,j], self.pair[v,j])]
                                            + self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[u,i], self.pair[v,j])])
                            q3 = 4.*(buv + b2*(self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[v,j], self.pair[v,j])]
                                             - self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[u,i], self.pair[v,j])]))
                            q4 = auv + b2*(self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[u,i], self.pair[u,i])]
                                         + self.g_mo[index(self.pair[v,j], self.pair[v,j], self.pair[v,j], self.pair[v,j])]
                                       -2.*self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[u,i], self.pair[v,j])])
                            # theta=root(q4,q3,q2,q1)%(math.pi*2)
                            theta=root(q4,q3,q2,q1)
                            # if abs(theta)>self.conv_tol[1]:
                            f=fun(q4, q3, q2, q1, theta); __e_ele=self.e_ele
                            orb1 = self.mo_coeff[:, self.pair[u, i]].copy()
                            orb2 = self.mo_coeff[:, self.pair[v, j]].copy()
                            self.mo_coeff[:, self.pair[u, i]] = orb1*math.cos(theta)+orb2*math.sin(theta)
                            self.mo_coeff[:, self.pair[v, j]] = -orb1*math.sin(theta)+orb2*math.cos(theta)
                            self.h_mo = reduce(numpy.dot, (self.mo_coeff.T, hcore, self.mo_coeff))
                            # self.g_mo = ao2mo.outcore.full_iofree(
                            #     self.mo_coeff[:, :self.nocc + self.npair_d],
                            #     self.mo_coeff[:, :self.nocc + self.npair_d])
                            self.g_mo = ao2mo.kernel(eri, self.mo_coeff[:,:self.nocc+self.nactvir])
                            # eri = self.mol.intor('int2e_cart', aosym='s8')
                            # self.g_mo = ao2mo.incore.full(ao2mo.restore(8, eri, self.nbs), self.mo_coeff)
                            deltaf=self.energy_elec()-__e_ele
                            self.opt_ci()
                            self.e_ele=self.energy_elec()
                            self.e_tot=self.e_ele+self.e_nuc; deltaE=self.e_ele-__e_ele
                            logger.note(self,' %3d %3d<->%3d %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f'
                              %(it+1,self.pair[u,i]+1,self.pair[v,j]+1,q4,q3,q2,q1,theta,self.e_tot,deltaE,f,deltaf))
                    for v in range(self.nocc,self.nocc+self.nactvir-self.npair_d):
                        j = 0
                        b2 = self.s(u)*self.ci[u,i]**2
                        auv = self.w(u,i,v,j,v,j) - self.w(u,i,u,i,u,i)
                        buv = self.w(u,i,u,i,v,j)
                        q1 = 4.*buv
                        q2 = 2.*(auv + b2*(self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[v,j], self.pair[v,j])]
                                         + self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[u,i], self.pair[v,j])]))
                        q3 = 4.*(buv + b2*(self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[v,j], self.pair[v,j])]
                                         - self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[u,i], self.pair[v,j])]))
                        q4 = 2.*auv + b2*(self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[u,i], self.pair[u,i])]
                                        + self.g_mo[index(self.pair[v,j], self.pair[v,j], self.pair[v,j], self.pair[v,j])]
                                      -2.*self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[u,i], self.pair[v,j])])
                        # theta=root(q4,q3,q2,q1)%(math.pi*2)
                        theta=root(q4,q3,q2,q1)
                        # if abs(theta)>self.conv_tol[1]:
                        f = fun(q4, q3, q2, q1, theta); __e_ele = self.e_ele
                        orb1 = self.mo_coeff[:, self.pair[u, i]].copy()
                        orb2 = self.mo_coeff[:, self.pair[v, j]].copy()
                        self.mo_coeff[:, self.pair[u, i]] = orb1*math.cos(theta)+orb2*math.sin(theta)
                        self.mo_coeff[:, self.pair[v, j]] = -orb1*math.sin(theta)+orb2*math.cos(theta)
                        self.h_mo = reduce(numpy.dot, (self.mo_coeff.T, hcore, self.mo_coeff))
                        self.g_mo = ao2mo.kernel(eri, self.mo_coeff[:,:self.nocc+self.nactvir])
                        # eri = self.mol.intor('int2e_cart', aosym='s8')
                        # self.g_mo = ao2mo.incore.full(ao2mo.restore(8, eri, self.nbs), self.mo_coeff)
                        deltaf = self.energy_elec() - __e_ele
                        self.opt_ci()
                        self.e_ele=self.energy_elec()
                        self.e_tot=self.e_ele+self.e_nuc; deltaE=self.e_ele-__e_ele
                        # logger.note(self,' %3d %3d<->%3d %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f'
                        #   %(it+1,self.pair[u,i]+1,self.pair[v,j]+1,q4,q3,q3,q2,theta,self.e_tot,deltaE, f, deltaf))
            # for _i in range(self.nocc-self.npair_d,self.nocc):
            #     print('%2d(%6f) <-> %2d(%6f)' %(self.pair[_i,0]+1, self.ci[_i,0], self.pair[_i,1]+1, self.ci[_i,1]))
            logger.note(self,' %3d  %11.8f   %12.9f' %(it+1, self.e_tot, self.e_ele-_e_ele))
            if abs(_e_ele-self.e_ele)<self.conv_tol[1]: break
            # else: rgvb.dump_mo(self, '%s_gvb_init-II.fchk' %in_pre2b, reffile)
        else: logger.error(self, 'Not converge in local optimization')
        logger.note(self, 'The GVB pair:')
        for _i in range(self.nocc-self.npair_d, self.nocc):
            logger.note(self, '%2d(%6f) <-> %2d(%6f)'
                        %(self.pair[_i,0]+1, self.ci[_i,0], self.pair[_i,1]+1, self.ci[_i,1]))
        self.e_tot=self.e_nuc+self.e_ele
        logger.note(self, 'gvb local converged energy = %11.8f' %self.e_tot)
        rgvb.dump_mo(self, '%s_gvb_init-II.fchk' %in_pre2b, reffile)

        self.h_mo = reduce(numpy.dot, (self.mo_coeff.T, hcore, self.mo_coeff))
        self.g_mo = ao2mo.kernel(eri, self.mo_coeff)
        logger.note(self, 'start global optimization iteration')
        logger.note(self, '  it       energy         delta')
        logger.note(self, '  it  obt1 orb2       q4           q3           q2           q1         theta       energy       delta(E)        fun        delta(f)')
        for it in range(self.max_cycle[0]):
            _e_ele = self.e_ele
            for u in reversed(range(self.nocc)):
                for i in range(2):
                    if u<self.nocc-self.npair_d and i==1: continue
                    for v in reversed(range(self.nocc-self.npair_d-self.nsig, self.nocc)):
                        for j in range(2):
                            if v < self.nocc - self.npair_d and j == 1: # 注意:单占据的geminal,只能j=0,不能j=1,
                                continue # 因为默认单占据s=0,若j取到1时,也被设置为s=0,而vj=1是core轨道,双占据,就不对了
                            if u==v and i==j: continue
                            b1 = 8*self.ci[u,i]**2 * self.ci[v,j]**2 * (1.-delta(u,v))
                            b2 = (self.s(u)*self.ci[u, i]**2 + self.s(v)*self.ci[v, j]**2
                                       - 2*self.s(u)*self.ci[u, i]*self.ci[v, j]*delta(u, v)
                                       - 2 * self.ci[u, i]**2 * self.ci[v, j]**2 * (2-self.t(u,v)) * (1.-delta(u,v)))
                            auv = (b1*(self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[v,j], self.pair[v,j])]
                                     - self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[u,i], self.pair[v,j])])
                                     +2.*(self.w(u,i,v,j,v,j) - self.w(u,i,u,i,u,i) - self.w(v,j,v,j,v,j) + self.w(v,j,u,i,u,i)))
                            buv = self.w(u,i,u,i,v,j) - self.w(v,j,u,i,v,j)
                            q1 = 4.*buv
                            q2 = auv + 2.*b2*(self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[v,j], self.pair[v,j])]
                                            + self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[u,i], self.pair[v,j])])
                            q3 = 4.*(buv + b2*(self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[v,j], self.pair[v,j])]
                                             - self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[u,i], self.pair[v,j])]))
                            q4 = auv + b2*(self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[u,i], self.pair[u,i])]
                                         + self.g_mo[index(self.pair[v,j], self.pair[v,j], self.pair[v,j], self.pair[v,j])]
                                       -2.*self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[u,i], self.pair[v,j])])
                            # theta=root(q4,q3,q2,q1)%(math.pi*2)
                            theta=root(q4,q3,q2,q1)
                            # if abs(theta-0.0)>self.conv_tol[0]:
                            f=fun(q4, q3, q2, q1, theta); __e_ele=self.e_ele
                            orb1 = self.mo_coeff[:, self.pair[u, i]].copy()
                            orb2 = self.mo_coeff[:, self.pair[v, j]].copy()
                            self.mo_coeff[:, self.pair[u, i]] = orb1*math.cos(theta)+orb2*math.sin(theta)
                            self.mo_coeff[:, self.pair[v, j]] = -orb1*math.sin(theta)+orb2*math.cos(theta)
                            self.h_mo = reduce(numpy.dot, (self.mo_coeff.T, hcore, self.mo_coeff))
                            self.g_mo = ao2mo.kernel(eri, self.mo_coeff)
                            # eri = self.mol.intor('int2e_cart', aosym='s8')
                            # self.g_mo = ao2mo.incore.full(ao2mo.restore(8, eri, self.nbs), self.mo_coeff)
                            deltaf=self.energy_elec()-__e_ele
                            self.opt_ci()
                            self.e_ele=self.energy_elec()
                            self.e_tot=self.e_ele+self.e_nuc; deltaE=self.e_ele-__e_ele
                            # logger.note(self,' %3d %3d<->%3d %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f'
                            #   %(it+1,self.pair[u,i]+1,self.pair[v,j]+1,q4,q3,q2,q1,theta,self.e_tot,deltaE,f,deltaf))
                    for v in range(self.nocc, self.npair_t):
                        j = 0
                        b2 = self.s(u)*self.ci[u,i]**2
                        auv = self.w(u,i,v,j,v,j) - self.w(u,i,u,i,u,i)
                        buv = self.w(u,i,u,i,v,j)
                        q1 = 4.*buv
                        q2 = 2.*(auv + b2*(self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[v,j], self.pair[v,j])]
                                         + self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[u,i], self.pair[v,j])]))
                        q3 = 4.*(buv + b2*(self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[v,j], self.pair[v,j])]
                                         - self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[u,i], self.pair[v,j])]))
                        q4 = 2.*auv + b2*(self.g_mo[index(self.pair[u,i], self.pair[u,i], self.pair[u,i], self.pair[u,i])]
                                        + self.g_mo[index(self.pair[v,j], self.pair[v,j], self.pair[v,j], self.pair[v,j])]
                                      -2.*self.g_mo[index(self.pair[u,i], self.pair[v,j], self.pair[u,i], self.pair[v,j])])
                        # theta=root(q4,q3,q2,q1)%(math.pi*2)
                        theta=root(q4,q3,q2,q1)
                        # if abs(theta-0.0)>self.conv_tol[0]:
                        f=fun(q4, q3, q2, q1, theta); __e_ele=self.e_ele
                        orb1 = self.mo_coeff[:, self.pair[u, i]].copy()
                        orb2 = self.mo_coeff[:, self.pair[v, j]].copy()
                        self.mo_coeff[:, self.pair[u, i]] = orb1*math.cos(theta)+orb2*math.sin(theta)
                        self.mo_coeff[:, self.pair[v, j]] = -orb1*math.sin(theta)+orb2*math.cos(theta)
                        self.h_mo = reduce(numpy.dot, (self.mo_coeff.T, hcore, self.mo_coeff))
                        self.g_mo = ao2mo.kernel(eri, self.mo_coeff)
                        # eri = self.mol.intor('int2e_cart', aosym='s8')
                        # self.g_mo = ao2mo.incore.full(ao2mo.restore(8, eri, self.nbs), self.mo_coeff)
                        deltaf = self.energy_elec() - __e_ele
                        self.opt_ci()
                        self.e_ele=self.energy_elec()
                        self.e_tot=self.e_ele+self.e_nuc; deltaE=self.e_ele-__e_ele
                        # logger.note(self,' %3d %3d<->%3d %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f'
                        #   %(it+1,self.pair[u,i]+1,self.pair[v,j]+1,q4,q3,q2,q1,theta,self.e_tot,deltaE,f,deltaf))
            # for _i in range(self.nocc-self.npair_d,self.nocc):
            #     print('%2d(%6f) <-> %2d(%6f)' %(self.pair[_i, 0]+1, self.ci[_i, 0], self.pair[_i, 1]+1, self.ci[_i, 1]))
            logger.note(self, ' %3d  %11.8f   %12.9f' % (it + 1, self.e_tot, self.e_ele - _e_ele))
            if abs(_e_ele-self.e_ele)<self.conv_tol[0]: break
            # else: rgvb.dump_mo(self, '%s_gvb_init-III.fchk' %in_pre2b, reffile)
        else: raise RuntimeError('Not converge in global optimization')
        logger.note(self, 'The GVB pair:')
        for _i in range(self.nocc - self.npair_d, self.nocc):
            logger.note(self, '%2d(%6f) <-> %2d(%6f)'
                        %(self.pair[_i,0]+1, self.ci[_i,0], self.pair[_i,1]+1, self.ci[_i,1]))
        self.e_tot=self.e_nuc+self.e_ele
        logger.note(self, 'gvb global converged energy = %11.8f' %self.e_tot)
        rgvb.dump_mo(self, '%s_gvb_init-III.fchk' % in_pre2b, reffile)