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, '----------------------------------------------')
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
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
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
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
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
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
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
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, '----------------------------------------------')
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, '----------------------------------------------')
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, '----------------------------------------------')