Пример #1
0
 def _finalize(self):
     if self.verbose >= lib.logger.NOTE:
         lib.logger.note(self,
                         '--------------- %s gradients ---------------',
                         self.base.__class__.__name__)
         rhf_grad._write(self, self.mol, self.de, self.atmlst)
         lib.logger.note(self,
                         '----------------------------------------------')
Пример #2
0
def grad_elec(mf_grad,
              mo_energy=None,
              mo_coeff=None,
              mo_occ=None,
              atmlst=None):
    '''
    Electronic part of UHF/UKS gradients

    Args:
        mf_grad : grad.uhf.Gradients or grad.uks.Gradients object
    '''
    mf = mf_grad.base
    mol = mf_grad.mol
    if mo_energy is None: mo_energy = mf.mo_energy
    if mo_occ is None: mo_occ = mf.mo_occ
    if mo_coeff is None: mo_coeff = mf.mo_coeff
    log = logger.Logger(mf_grad.stdout, mf_grad.verbose)

    hcore_deriv = mf_grad.hcore_generator(mol)
    s1 = mf_grad.get_ovlp(mol)
    dm0 = mf.make_rdm1(mo_coeff, mo_occ)

    t0 = (time.clock(), time.time())
    log.debug('Computing Gradients of NR-UHF Coulomb repulsion')
    vhf = mf_grad.get_veff(mol, dm0)
    log.timer('gradients of 2e part', *t0)

    dme0 = mf_grad.make_rdm1e(mo_energy, mo_coeff, mo_occ)
    dm0_sf = dm0[0] + dm0[1]
    dme0_sf = dme0[0] + dme0[1]

    if atmlst is None:
        atmlst = range(mol.natm)
    aoslices = mol.aoslice_by_atom()
    de = numpy.zeros((len(atmlst), 3))
    for k, ia in enumerate(atmlst):
        shl0, shl1, p0, p1 = aoslices[ia]
        h1ao = hcore_deriv(ia)
        de[k] += numpy.einsum('xij,ij->x', h1ao, dm0_sf)
        # s1, vhf are \nabla <i|h|j>, the nuclear gradients = -\nabla
        de[k] += numpy.einsum('sxij,sij->x', vhf[:, :, p0:p1], dm0[:,
                                                                   p0:p1]) * 2
        de[k] -= numpy.einsum('xij,ij->x', s1[:, p0:p1], dme0_sf[p0:p1]) * 2

        de[k] += mf_grad.extra_force(ia, locals())

    if log.verbose >= logger.DEBUG:
        log.debug('gradients of electronic part')
        rhf_grad._write(log, mol, de, atmlst)
    return de
Пример #3
0
        def kernel(self, dm=None, atmlst=None):
            if dm is None:
                dm = self.base.make_rdm1(ao_repr=True)

            # de_solvent needs to be called first because _finalize method
            # is called in the grad_method.kernel function.  de_solvent is
            # required by the _finalize method.
            self.de_solvent = kernel(self.with_solvent, dm)
            self.de_solute = grad_method_class.kernel(self, atmlst=atmlst)
            self.de = self.de_solute + self.de_solvent

            if self.verbose >= logger.NOTE:
                logger.note(self, '--------------- %s (%s) gradients ---------------',
                            self.base.__class__.__name__,
                            self.with_solvent.__class__.__name__)
                rhf_grad._write(self, self.mol, self.de, self.atmlst)
                logger.note(self, '----------------------------------------------')
            return self.de
Пример #4
0
        def kernel(self, *args, **kwargs):
            dm = kwargs.pop('dm', None)
            if dm is None:
                dm = self.base.make_rdm1(ao_repr=True)

            self.de_solvent = kernel(self.base.with_solvent, dm)
            self.de_solute = grad_method_class.kernel(self, *args, **kwargs)
            self.de = self.de_solute + self.de_solvent

            if self.verbose >= logger.NOTE:
                logger.note(
                    self, '--------------- %s (+%s) gradients ---------------',
                    self.base.__class__.__name__,
                    self.base.with_solvent.__class__.__name__)
                rhf_grad._write(self, self.mol, self.de, self.atmlst)
                logger.note(self,
                            '----------------------------------------------')
            return self.de
Пример #5
0
        def kernel(self, dm=None, atmlst=None):
            if dm is None:
                dm = grad_method.base.make_rdm1(ao_repr=True)

            # de_solvent needs to be called first because _finalize method
            # is called in the grad_method.kernel function.  de_solvent is
            # required by the _finalize method.
            self.de_solvent = kernel(self.with_solvent, dm)
            self.de_solute = grad_method_class.kernel(self, atmlst=atmlst)
            self.de = self.de_solute + self.de_solvent

            if self.verbose >= logger.NOTE:
                logger.note(self, '--------------- %s (%s) gradients ---------------',
                            grad_method.base.__class__.__name__,
                            self.with_solvent.__class__.__name__)
                rhf_grad._write(self, self.mol, self.de, self.atmlst)
                logger.note(self, '----------------------------------------------')
            return self.de
Пример #6
0
    def kernel(self, level_shift=None, **kwargs):
        cput0 = (time.clock(), time.time())
        log = lib.logger.new_logger(self, self.verbose)
        if 'atmlst' in kwargs:
            self.atmlst = kwargs['atmlst']
        #self.natm = len (self.atmlst)

        if self.verbose >= lib.logger.WARN:
            self.check_sanity()
        if self.verbose >= lib.logger.INFO:
            self.dump_flags()

        conv, Lvec, bvec, Aop, Adiag = self.solve_lagrange(
            level_shift=level_shift, **kwargs)
        self.debug_lagrange(Lvec, bvec, Aop, Adiag, **kwargs)
        #if not conv: raise RuntimeError ('Lagrange multiplier determination not converged!')
        cput1 = lib.logger.timer(self, 'Lagrange gradient multiplier solution',
                                 *cput0)

        ham_response = self.get_ham_response(**kwargs)
        lib.logger.info(
            self,
            '--------------- %s gradient Hamiltonian response ---------------',
            self.base.__class__.__name__)
        rhf_grad._write(self, self.mol, ham_response, self.atmlst)
        lib.logger.info(self, '----------------------------------------------')
        cput1 = lib.logger.timer(
            self, 'Lagrange gradient Hellmann-Feynman determination', *cput1)

        LdotJnuc = self.get_LdotJnuc(Lvec, **kwargs)
        lib.logger.info(
            self,
            '--------------- %s gradient Lagrange response ---------------',
            self.base.__class__.__name__)
        rhf_grad._write(self, self.mol, LdotJnuc, self.atmlst)
        lib.logger.info(self, '----------------------------------------------')
        cput1 = lib.logger.timer(self, 'Lagrange gradient Jacobian', *cput1)

        self.de = ham_response + LdotJnuc
        log.timer('Lagrange gradients', *cput0)
        self._finalize()
        return self.de
Пример #7
0
    def get_LdotJnuc (self, Lvec, state=None, atmlst=None, verbose=None, mo=None, ci=None, eris=None, mf_grad=None, **kwargs):
        if state is None: state = self.state
        if atmlst is None: atmlst = self.atmlst
        if verbose is None: verbose = self.verbose
        if mo is None: mo = self.base.mo_coeff
        if ci is None: ci = self.base.ci[state]
        if eris is None and self.eris is None:
            eris = self.eris = self.base.ao2mo (mo)
        elif eris is None:
            eris = self.eris
        ncas = self.base.ncas
        nelecas = self.base.nelecas
        if getattr(self.base.fcisolver, 'gen_linkstr', None):
            linkstr  = self.base.fcisolver.gen_linkstr(ncas, nelecas, False)
        else:
            linkstr  = None

        # Just sum the weights now... Lorb can be implicitly summed
        # Lci may be in the csf basis
        Lorb, Lci = self.unpack_uniq_var (Lvec)
        #Lorb = self.base.unpack_uniq_var (Lvec[:self.ngorb])
        #Lci = Lvec[self.ngorb:].reshape (self.nroots, -1)
        #ci = np.ravel (ci).reshape (self.nroots, -1)

        # CI part
        t0 = (time.clock (), time.time ())
        de_Lci = Lci_dot_dgci_dx (Lci, self.weights, self.base, mo_coeff=mo, ci=ci, atmlst=atmlst, mf_grad=mf_grad, eris=eris, verbose=verbose)
        lib.logger.info (self, '--------------- %s gradient Lagrange CI response ---------------',
                    self.base.__class__.__name__)
        if verbose >= lib.logger.INFO: rhf_grad._write(self, self.mol, de_Lci, atmlst)
        lib.logger.info (self, '----------------------------------------------------------------')
        t0 = lib.logger.timer (self, '{} gradient Lagrange CI response'.format (self.base.__class__.__name__), *t0)

        # Orb part
        de_Lorb = Lorb_dot_dgorb_dx (Lorb, self.base, mo_coeff=mo, ci=ci, atmlst=atmlst, mf_grad=mf_grad, eris=eris, verbose=verbose)
        lib.logger.info (self, '--------------- %s gradient Lagrange orbital response ---------------',
                    self.base.__class__.__name__)
        if verbose >= lib.logger.INFO: rhf_grad._write(self, self.mol, de_Lorb, atmlst)
        lib.logger.info (self, '----------------------------------------------------------------------')
        t0 = lib.logger.timer (self, '{} gradient Lagrange orbital response'.format (self.base.__class__.__name__), *t0)

        return de_Lci + de_Lorb
Пример #8
0
def grad_elec(mf_grad, mo_energy=None, mo_coeff=None, mo_occ=None, atmlst=None):
    mf = mf_grad.base
    mol = mf_grad.mol
    if mo_energy is None: mo_energy = mf.mo_energy
    if mo_occ is None:    mo_occ = mf.mo_occ
    if mo_coeff is None:  mo_coeff = mf.mo_coeff
    log = logger.Logger(mf_grad.stdout, mf_grad.verbose)

    hcore_deriv = mf_grad.hcore_generator(mol)
    s1 = mf_grad.get_ovlp(mol)
    dm0 = mf.make_rdm1(mo_coeff, mo_occ)

    t0 = (time.clock(), time.time())
    log.debug('Computing Gradients of NR-UHF Coulomb repulsion')
    vhf = mf_grad.get_veff(mol, dm0)
    log.timer('gradients of 2e part', *t0)

    dme0 = mf_grad.make_rdm1e(mo_energy, mo_coeff, mo_occ)
    dm0_sf = dm0[0] + dm0[1]
    dme0_sf = dme0[0] + dme0[1]

    if atmlst is None:
        atmlst = range(mol.natm)
    aoslices = mol.aoslice_by_atom()
    de = numpy.zeros((len(atmlst),3))
    for k, ia in enumerate(atmlst):
        shl0, shl1, p0, p1 = aoslices[ia]
        h1ao = hcore_deriv(ia)
        de[k] += numpy.einsum('xij,ij->x', h1ao, dm0_sf)
# s1, vhf are \nabla <i|h|j>, the nuclear gradients = -\nabla
        de[k] += numpy.einsum('sxij,sij->x', vhf[:,:,p0:p1], dm0[:,p0:p1]) * 2
        de[k] -= numpy.einsum('xij,ij->x', s1[:,p0:p1], dme0_sf[p0:p1]) * 2

        de[k] += mf_grad.extra_force(ia, locals())

    if log.verbose >= logger.DEBUG:
        log.debug('gradients of electronic part')
        rhf_grad._write(log, mol, de, atmlst)
    return de
Пример #9
0
 def _finalize(self):
     if self.verbose >= logger.NOTE:
         logger.note(self, '--------------- %s gradients ---------------',
                     self.base.__class__.__name__)
         rhf_grad._write(self, self.mol, self.de, self.atmlst)
         logger.note(self, '----------------------------------------------')
Пример #10
0
 def _finalize(self):
     if self.verbose >= logger.NOTE:
         logger.note(self, '--------- %s gradients for state %d ----------',
                     self.base.__class__.__name__, self.state)
         rhf_grad._write(self, self.mol, self.de, self.atmlst)
         logger.note(self, '----------------------------------------------')
Пример #11
0
 def _finalize(self):
     if self.verbose >= logger.NOTE:
         logger.note(self, '--------------- %s gradients ---------------',
                     self.base.__class__.__name__)
         _write(self, self.mol, self.de, None)
         logger.note(self, '----------------------------------------------')