def fast_newton(mf, mo_coeff=None, mo_occ=None, dm0=None, auxbasis=None, projectbasis=None, **newton_kwargs): '''Wrap function to quickly setup and call Newton solver. Newton solver attributes [max_cycle_inner, max_stepsize, ah_start_tol, ah_conv_tol, ah_grad_trust_region, ...] can be passed through **newton_kwargs. ''' import copy from pyscf.lib import logger from pyscf import df if auxbasis is None: auxbasis = df.addons.aug_etb_for_dfbasis(mf.mol, 'ahlrichs', beta=2.5) if projectbasis: mf1 = newton(mf) pmol = mf1.mol = newton_ah.project_mol(mf.mol, projectbasis) mf1 = density_fit(mf1, auxbasis) else: mf1 = density_fit(newton(mf), auxbasis) mf1.direct_scf_tol = 1e-7 if hasattr(mf, 'grids'): from pyscf.dft import gen_grid approx_grids = gen_grid.Grids(mf.mol) approx_grids.verbose = 0 approx_grids.level = max(0, mf.grids.level - 2) mf1.grids = approx_grids approx_numint = copy.copy(mf._numint) mf1._numint = approx_numint for key in newton_kwargs: setattr(mf1, key, newton_kwargs[key]) if mo_coeff is None or mo_occ is None: mo_coeff, mo_occ = mf.mo_coeff, mf.mo_occ if dm0 is not None: mo_coeff, mo_occ = mf1.from_dm(dm0) elif mo_coeff is None or mo_occ is None: logger.note( mf, '========================================================') logger.note( mf, 'Generating initial guess with DIIS-SCF for newton solver') logger.note( mf, '========================================================') if projectbasis: mf0 = copy.copy(mf) mf0.mol = pmol mf0 = density_fit(mf0, auxbasis) else: mf0 = density_fit(mf, auxbasis) mf0.direct_scf_tol = 1e-7 mf0.conv_tol = 3. mf0.conv_tol_grad = 1. if mf0.level_shift == 0: mf0.level_shift = .2 if hasattr(mf, 'grids'): mf0.grids = approx_grids mf0._numint = approx_numint # Note: by setting small_rho_cutoff, dft.get_veff function may overwrite # approx_grids and approx_numint. It will further changes the corresponding # mf1 grids and _numint. If inital guess dm0 or mo_coeff/mo_occ were given, # dft.get_veff are not executed so that more grid points may be found in # approx_grids. mf0.small_rho_cutoff = mf.small_rho_cutoff * 10 mf0.kernel() mo_coeff, mo_occ = mf0.mo_coeff, mf0.mo_occ if projectbasis: if mo_occ.ndim == 2: mo_coeff = (project_mo_nr2nr(pmol, mo_coeff[0], mf.mol), project_mo_nr2nr(pmol, mo_coeff[1], mf.mol)) else: mo_coeff = project_mo_nr2nr(pmol, mo_coeff, mf.mol) mo_coeff, mo_occ = mf1.from_dm(mf.make_rdm1(mo_coeff, mo_occ)) logger.note(mf, '============================') logger.note(mf, 'Generating initial guess end') logger.note(mf, '============================') mf1.kernel(mo_coeff, mo_occ) mf.converged = mf1.converged mf.e_tot = mf1.e_tot mf.mo_energy = mf1.mo_energy mf.mo_coeff = mf1.mo_coeff mf.mo_occ = mf1.mo_occ mf = copy.copy(mf) def mf_kernel(*args, **kwargs): logger.warn( mf, "fast_newton is a wrap function to quickly setup and call Newton solver. " "There's no need to call kernel function again for fast_newton.") del (mf.kernel) # warn once and remove circular depdence return mf.e_tot mf.kernel = mf_kernel return mf
def fast_newton(mf, mo_coeff=None, mo_occ=None, dm0=None, auxbasis=None, projectbasis=None, **newton_kwargs): '''Wrap function to quickly setup and call Newton solver. Newton solver attributes [max_cycle_inner, max_stepsize, ah_start_tol, ah_conv_tol, ah_grad_trust_region, ...] can be passed through **newton_kwargs. ''' import copy from pyscf.lib import logger from pyscf import df if auxbasis is None: auxbasis = df.addons.aug_etb_for_dfbasis(mf.mol, 'ahlrichs', beta=2.5) if projectbasis: mf1 = newton(mf) pmol = mf1.mol = newton_ah.project_mol(mf.mol, projectbasis) mf1 = density_fit(mf1, auxbasis) else: mf1 = density_fit(newton(mf), auxbasis) mf1.direct_scf_tol = 1e-7 if hasattr(mf, 'grids'): from pyscf.dft import gen_grid approx_grids = gen_grid.Grids(mf.mol) approx_grids.verbose = 0 approx_grids.level = 0 mf1.grids = approx_grids approx_numint = copy.copy(mf._numint) mf1._numint = approx_numint for key in newton_kwargs: setattr(mf1, key, newton_kwargs[key]) if mo_coeff is None or mo_occ is None: mo_coeff, mo_occ = mf.mo_coeff, mf.mo_occ if dm0 is not None: mo_coeff, mo_occ = mf1.from_dm(dm0) elif mo_coeff is None or mo_occ is None: logger.note(mf, '========================================================') logger.note(mf, 'Generating initial guess with DIIS-SCF for newton solver') logger.note(mf, '========================================================') if projectbasis: mf0 = copy.copy(mf) mf0.mol = pmol mf0 = density_fit(mf0, auxbasis) else: mf0 = density_fit(mf, auxbasis) mf0.direct_scf_tol = 1e-7 mf0.conv_tol = 3. mf0.conv_tol_grad = 1. if mf0.level_shift == 0: mf0.level_shift = .2 if hasattr(mf, 'grids'): mf0.grids = approx_grids mf0._numint = approx_numint # Note: by setting small_rho_cutoff, dft.get_veff function may overwrite # approx_grids and approx_numint. It will further changes the corresponding # mf1 grids and _numint. If inital guess dm0 or mo_coeff/mo_occ were given, # dft.get_veff are not executed so that more grid points may be found in # approx_grids. mf0.small_rho_cutoff = 1e-5 mf0.kernel() mo_coeff, mo_occ = mf0.mo_coeff, mf0.mo_occ if projectbasis: if mo_occ.ndim == 2: mo_coeff =(project_mo_nr2nr(pmol, mo_coeff[0], mf.mol), project_mo_nr2nr(pmol, mo_coeff[1], mf.mol)) else: mo_coeff = project_mo_nr2nr(pmol, mo_coeff, mf.mol) mo_coeff, mo_occ = mf1.from_dm(mf.make_rdm1(mo_coeff,mo_occ)) logger.note(mf, '============================') logger.note(mf, 'Generating initial guess end') logger.note(mf, '============================') mf1.kernel(mo_coeff, mo_occ) mf.converged = mf1.converged mf.e_tot = mf1.e_tot mf.mo_energy = mf1.mo_energy mf.mo_coeff = mf1.mo_coeff mf.mo_occ = mf1.mo_occ def mf_kernel(*args, **kwargs): logger.warn(mf, "fast_newton is a wrap function to quickly setup and call Newton solver. " "There's no need to call kernel function again for fast_newton.") del(mf.kernel) # warn once and remove circular depdence return mf.e_tot mf.kernel = mf_kernel return mf