def test_gen_grid(self): grid = gen_grid.Grids(h2o) grid.prune = None grid.radi_method = radi.gauss_chebyshev grid.becke_scheme = gen_grid.original_becke grid.radii_adjust = radi.becke_atomic_radii_adjust grid.atomic_radii = radi.BRAGG_RADII grid.atom_grid = { "H": (10, 50), "O": (10, 50), } coord, weight = grid.build() self.assertAlmostEqual(numpy.linalg.norm(coord), 185.91245945279027, 9) self.assertAlmostEqual(numpy.linalg.norm(weight), 1720.1317185648893, 8) grid.becke_scheme = gen_grid.stratmann coord, weight = grid.build() self.assertAlmostEqual(numpy.linalg.norm(weight), 1730.3692983091271, 8) grid.atom_grid = { "O": (10, 50), } grid.radii_adjust = None grid.becke_scheme = gen_grid.stratmann coord, weight = grid.build() self.assertAlmostEqual(numpy.linalg.norm(weight), 2559.0064040257907, 8)
def test_prune(self): grid = gen_grid.Grids(h2o) grid.prune = gen_grid.sg1_prune grid.atom_grid = { "H": (10, 50), "O": (10, 50), } grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.coords), 202.17732600266302, 9) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 442.54536463517167, 9) grid.prune = gen_grid.nwchem_prune grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.coords), 149.55023044392638, 9) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 586.36841824004455, 9) z = 16 rad, dr = radi.gauss_chebyshev(50) angs = gen_grid.sg1_prune(z, rad, 434, radii=radi.SG1RADII) self.assertAlmostEqual(lib.fp(angs), -291.0794420982329, 9) angs = gen_grid.nwchem_prune(z, rad, 434, radii=radi.BRAGG_RADII) self.assertAlmostEqual(lib.fp(angs), -180.12023039394498, 9) angs = gen_grid.nwchem_prune(z, rad, 26, radii=radi.BRAGG_RADII) self.assertTrue(numpy.all(angs == 26))
def _dft_common_init_(mf): mf.xc = 'LDA,VWN' mf.nlc = '' mf.grids = gen_grid.Grids(mf.mol) mf.grids.level = getattr(__config__, 'dft_rks_RKS_grids_level', mf.grids.level) mf.nlcgrids = gen_grid.Grids(mf.mol) mf.nlcgrids.level = getattr(__config__, 'dft_rks_RKS_nlcgrids_level', mf.nlcgrids.level) # Use rho to filter grids mf.small_rho_cutoff = getattr(__config__, 'dft_rks_RKS_small_rho_cutoff', 1e-7) ################################################## # don't modify the following attributes, they are not input options mf._numint = numint.NumInt() mf._keys = mf._keys.union(['xc', 'nlc', 'omega', 'grids', 'nlcgrids', 'small_rho_cutoff'])
def get_elec(dmA, dmB): """ Args: dmA/dmB: 2D array density matrix, size of (ao,ao). ao is the number of atomic orbitals """ grids = gen_grid.Grids(system) grids.level = 4 grids.build() rho1_grid = get_density_from_dm(wrap.mol1, dmB, grids.coords) # write the electron density to a cube file rho = rho_both.reshape(cc.nx, cc.ny, cc.nz) cc.write(rho, 'rho.cube', comment='Electron density in real space (e/Bohr^3)') # Coulomb repulsion potential v_coul = coulomb_potential_grid(points, grids.coords, grids.weights, rho1_grid) # Nuclear-electron attraction potential mol1_charges, mol1_coords = get_charges_and_coords(B_mol) v1_nuc0 = np.zeros(rho0.shape) for j, point in enumerate(points): for i in range(len(mol1_charges)): d = np.linalg.norm(point - mol1_coords[i]) if d >= 1e-5: v1_nuc0[j] += -mol1_charges[i] / d v_elec = v_coul + v1_nuc0 return v_elec
def test_gen_atomic_grids(self): grid = gen_grid.Grids(h2o) grid.prune = None grid.atom_grid = { "H": (10, 58), "O": (10, 50), } self.assertRaises(ValueError, grid.build)
def _dft_common_init_(mf): mf.xc = 'LDA,VWN' mf.grids = gen_grid.Grids(mf.mol) mf.small_rho_cutoff = 1e-7 # Use rho to filter grids ################################################## # don't modify the following attributes, they are not input options mf._numint = numint._NumInt() mf._keys = mf._keys.union(['xc', 'grids', 'small_rho_cutoff'])
def get_grid(mol, gridlevel=4, obj=False): """ """ grid = gen_grid.Grids(mol) grid.level = gridlevel grid.build() to_return = grid if obj else (grid.coords, grid.weights) return to_return
def compute_nad_terms(mol0, mol1, dm0, dm1, emb_args): """Compute the non-additive potentials and energies. Parameters ---------- mol : PySCF gto.M Molecule objects. emb_args : dict Information of embedding calculation. """ # Create supersystem newatom = '\n'.join([mol0.atom, mol1.atom]) system = gto.M(atom=newatom, basis=mol0.basis) # Construct grid for complex grids = gen_grid.Grids(system) grids.level = 4 grids.build() ao_mol0 = eval_ao(mol0, grids.coords, deriv=0) ao_mol1 = eval_ao(mol1, grids.coords, deriv=0) # Make Complex DM ao_both = eval_ao(system, grids.coords, deriv=0) nao_mol0 = mol0.nao_nr() nao_mol1 = mol1.nao_nr() nao_tot = nao_mol0 + nao_mol1 dm_both = np.zeros((nao_tot, nao_tot)) dm_both[:nao_mol0, :nao_mol0] = dm0 dm_both[nao_mol0:, nao_mol0:] = dm1 # Compute DFT non-additive potential and energies rho_mol0 = eval_rho(mol0, ao_mol0, dm0, xctype='LDA') rho_mol1 = eval_rho(mol1, ao_mol1, dm1, xctype='LDA') rho_both = eval_rho(system, ao_both, dm_both, xctype='LDA') # Compute all densities on a grid xc_code = emb_args["xc_code"] t_code = emb_args["t_code"] excs, vxcs = get_dft_grid_stuff(xc_code, rho_both, rho_mol0, rho_mol1) ets, vts = get_dft_grid_stuff(t_code, rho_both, rho_mol0, rho_mol1) vxc_emb = vxcs[0][0] - vxcs[1][0] vt_emb = vts[0][0] - vts[1][0] # Energy functionals: exc_nad = get_nad_energy(grids, excs, rho_both, rho_mol0, rho_mol1) et_nad = get_nad_energy(grids, ets, rho_both, rho_mol0, rho_mol1) v_nad_xc = eval_mat(mol0, ao_mol0, grids.weights, rho_mol0, vxc_emb, xctype='LDA') v_nad_t = eval_mat(mol0, ao_mol0, grids.weights, rho_mol0, vt_emb, xctype='LDA') return (exc_nad, et_nad, v_nad_xc, v_nad_t)
def __init__(self, mol): dhf.UHF.__init__(self, mol) self.xc = 'LDA,VWN' self.grids = gen_grid.Grids(self.mol) self.small_rho_cutoff = 1e-7 # Use rho to filter grids ################################################## # don't modify the following attributes, they are not input options self._numint = r_numint._RNumInt() self._keys = self._keys.union(['xc', 'grids', 'small_rho_cutoff'])
def test_overwriting_grids_attribute(self): g = gen_grid.Grids(h2o).run() self.assertEqual(g.weights.size, 34310) g.atom_grid = { "H": (10, 110), "O": (10, 110), } self.assertTrue(g.weights is None)
def test_make_mask(self): grid = gen_grid.Grids(h2o) grid.atom_grid = { "H": (10, 110), "O": (10, 110), } grid.build() coords = grid.coords * 10. non0 = gen_grid.make_mask(h2o, coords) self.assertEqual(non0.sum(), 122) self.assertAlmostEqual(lib.fp(non0), 0.554275491306796, 9)
def test_make_mask(self): grid = gen_grid.Grids(h2o) grid.atom_grid = { "H": (10, 110), "O": (10, 110), } grid.build() coords = grid.coords * 10. non0 = gen_grid.make_mask(h2o, coords) self.assertEqual(non0.sum(), 106) self.assertAlmostEqual(lib.finger(non0), -0.81399929716237085, 9)
def test_prune(self): grid = gen_grid.Grids(h2o) grid.prune = gen_grid.sg1_prune grid.atom_grid = {"H": (10, 50), "O": (10, 50),} coord, weight = grid.build() self.assertAlmostEqual(numpy.linalg.norm(coord), 202.17732600266302, 9) self.assertAlmostEqual(numpy.linalg.norm(weight), 442.54536463517167, 9) grid.prune = gen_grid.nwchem_prune coord, weight = grid.build() self.assertAlmostEqual(numpy.linalg.norm(coord), 149.55023044392638, 9) self.assertAlmostEqual(numpy.linalg.norm(weight), 586.36841824004455, 9)
def __init__(self, mol): dhf.UHF.__init__(self, mol) self.xc = 'LDA,VWN' self.grids = gen_grid.Grids(self.mol) self.grids.level = getattr(__config__, 'dft_rks_RKS_grids_level', self.grids.level) # Use rho to filter grids self.small_rho_cutoff = getattr(__config__, 'dft_rks_RKS_small_rho_cutoff', 1e-7) ################################################## # don't modify the following attributes, they are not input options self._numint = r_numint.RNumInt() self._keys = self._keys.union(['xc', 'grids', 'small_rho_cutoff'])
def test_radi(self): grid = gen_grid.Grids(h2o) grid.prune = None grid.radii_adjust = radi.becke_atomic_radii_adjust grid.atomic_radii = radi.COVALENT_RADII grid.radi_method = radi.mura_knowles grid.atom_grid = {"H": (10, 50), "O": (10, 50),} coord, weight = grid.build() self.assertAlmostEqual(numpy.linalg.norm(weight), 1804.5437331817291, 9) grid.radi_method = radi.delley coord, weight = grid.build() self.assertAlmostEqual(numpy.linalg.norm(weight), 1686.3482864673697, 9)
def __init__(self, mol): self.mol = mol self.stdout = mol.stdout self.verbose = mol.verbose self.max_memory = mol.max_memory #self.radii_table = radii.VDW self.radii_table = radii.UFF * 1.1 #self.radii_table = radii.MM3 self.atom_radii = None self.lebedev_order = 17 self.lmax = 6 # max angular momentum of spherical harmonics basis self.eta = .1 # regularization parameter self.eps = 78.3553 self.grids = gen_grid.Grids(mol) # The maximum iterations and convergence tolerance to update solvent # effects in CASCI, CC, MP, CI, ... methods self.max_cycle = 20 self.conv_tol = 1e-7 self.state_id = 0 # Set frozen to enable/disable the frozen ddCOSMO solvent potential. # If frozen is set, _dm (density matrix) needs to be specified to # generate the potential. self.frozen = False # In the rapid process (such as vertical excitation), solvent does not # follow the fast change of electronic structure of solutes. A # calculation of non-equilibrium solvation should be used. For slow # process (like geometry optimization), solvent has enough time to # respond to the changes in electronic structure or geometry of # solutes. Equilibrium solvation should be enabled in the calculation. # See for example JPCA, 104, 5631 (2000) # # Note this attribute has no effects if .frozen is enabled. # self.equilibrium_solvation = False ################################################## # don't modify the following attributes, they are not input options # e (the dielectric correction) and v (the additional potential) are # updated during the SCF iterations self.e = None self.v = None self._dm = None self._intermediates = None self._keys = set(self.__dict__.keys())
def __init__(self, mol): if mol.nelectron.__mod__(2) != 0: raise ValueError('Invalid electron number %i.' % mol.nelectron) X2C_RHF.__init__(self, mol) self.xc = 'LDA,VWN' self.grids = gen_grid.Grids(self.mol) self.grids.level = getattr(__config__, 'dft_rks_RKS_grids_level', self.grids.level) # Use rho to filter grids self.small_rho_cutoff = getattr(__config__, 'dft_rks_RKS_small_rho_cutoff', 1e-7) ################################################## # don't modify the following attributes, they are not input options self._numint = r_numint.RNumInt() self._keys = self._keys.union(['xc', 'grids', 'small_rho_cutoff'])
def __init__(self, mol): self.mol = mol self.stdout = mol.stdout self.verbose = mol.verbose self.max_memory = mol.max_memory #self.radii_table = radii.VDW self.radii_table = radii.UFF * 1.1 #self.radii_table = radii.MM3 self.atom_radii = None self.lebedev_order = 17 self.lmax = 6 # max angular momentum of spherical harmonics basis self.eta = .1 # regularization parameter self.eps = 78.3553 self.grids = gen_grid.Grids(mol) ################################################## # don't modify the following attributes, they are not input options self._keys = set(self.__dict__.keys())
def __init__(self, mol, mm_mol=None): self.mol = mol self.mm_mol = mm_mol self.stdout = mol.stdout self.verbose = mol.verbose self.max_memory = mol.max_memory #self.radii_table = radii.VDW self.radii_table = radii.UFF * 1.1 #self.radii_table = radii.MM3 self.atom_radii = None self.lebedev_order = 17 self.lmax = 6 # max angular momentum of spherical harmonics basis self.eta = .1 # regularization parameter self.eps = 78.3553 self.grids = gen_grid.Grids( mol) # Generate grids of QM atoms, but no of MM atoms # The maximum iterations and convergence tolerance to update solvent # effects in CASCI, CC, MP, CI, ... methods self.max_cycle = 20 self.conv_tol = 1e-7 self.state_id = 0 # Set frozen to enable/disable the frozen ddCOSMO solvent potential. # If frozen is set, _dm (density matrix) needs to be specified to # generate the potential. self.frozen = False ################################################## # don't modify the following attributes, they are not input options # epcm (the dielectric correction) and vpcm (the additional # potential) are updated during the SCF iterations self.epcm = None self.vpcm = None self._dm = None # _solver_ is a cached function returned by self.as_solver() to reduce # the overhead of initialization. It should be cleared whenever the # solvent parameters or the integration grids were changed. self._solver_ = None self._keys = set(self.__dict__.keys())
def test_radi(self): grid = gen_grid.Grids(h2o) grid.prune = None grid.radii_adjust = radi.becke_atomic_radii_adjust grid.atomic_radii = radi.COVALENT_RADII grid.radi_method = radi.mura_knowles grid.atom_grid = { "H": (10, 50), "O": (10, 50), } grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 1804.5437331817291, 9) grid.radi_method = radi.delley grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 1686.3482864673697, 9) grid.radi_method = radi.becke grid.build(with_non0tab=False) self.assertAlmostEqual(lib.fp(grid.weights), 2486249.209827192, 7)
def get_gridss(mol, level=1, gthrd=1e-10): Ktime = (logger.process_clock(), logger.perf_counter()) grids = gen_grid.Grids(mol) grids.level = level grids.build() ngrids = grids.weights.size mask = [] for p0, p1 in lib.prange(0, ngrids, 10000): ao_v = mol.eval_gto('GTOval', grids.coords[p0:p1]) ao_v *= grids.weights[p0:p1,None] wao_v0 = ao_v mask.append(numpy.any(wao_v0>gthrd, axis=1) | numpy.any(wao_v0<-gthrd, axis=1)) mask = numpy.hstack(mask) grids.coords = grids.coords[mask] grids.weights = grids.weights[mask] logger.debug(mol, 'threshold for grids screening %g', gthrd) logger.debug(mol, 'number of grids %d', grids.weights.size) logger.timer_debug1(mol, "Xg screening", *Ktime) return grids
def test_gen_grid(self): grid = gen_grid.Grids(h2o) grid.prune = None grid.radi_method = radi.gauss_chebyshev grid.becke_scheme = gen_grid.original_becke grid.radii_adjust = radi.becke_atomic_radii_adjust grid.atomic_radii = radi.BRAGG_RADII grid.atom_grid = { "H": (10, 50), "O": (10, 50), } grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.coords), 185.91245945279027, 9) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 1720.1317185648893, 8) grid.becke_scheme = gen_grid.stratmann grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 1730.3692983091271, 8) grid.atom_grid = { "O": (10, 50), } grid.radii_adjust = None grid.becke_scheme = gen_grid.stratmann grid.kernel(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 2559.0064040257907, 8) grid.atom_grid = (10, 11) grid.becke_scheme = gen_grid.original_becke grid.radii_adjust = None grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 1712.3069450297105, 8)
def run_co_h2o_pyscf(ibasis, return_matrices=False): # Run SCF in pyscf h2o = gto.M( atom=""" O -7.9563726699 1.4854060709 0.1167920007 H -6.9923165534 1.4211335985 0.1774706091 H -8.1058463545 2.4422204631 0.1115993752 """, basis=ibasis, ) co = gto.M( atom=""" C -3.6180905689 1.3768035675 -0.0207958979 O -4.7356838533 1.5255563000 0.1150239130 """, basis=ibasis, ) system = gto.M(atom=co.atom + h2o.atom, basis=ibasis) # Get initial densities from HF # H2O # TODO: make a wrapper and make sure DMs are correct scfres1 = scf.RHF(h2o) scfres1.conv_tol = 1e-12 scfres1.kernel() dmb = scfres1.make_rdm1() # CO scfres2 = scf.RHF(co) scfres2.conv_tol = 1e-12 scfres2.kernel() dma = scfres2.make_rdm1() # Construct grid for complex grids = gen_grid.Grids(system) grids.level = 4 grids.build() ao_h2o = eval_ao(h2o, grids.coords, deriv=0) ao_co = eval_ao(co, grids.coords, deriv=0) # Make Complex DM ao_both = eval_ao(system, grids.coords, deriv=0) nao_co = co.nao_nr() nao_h2o = h2o.nao_nr() nao_tot = nao_co + nao_h2o dm_both = np.zeros((nao_tot, nao_tot)) dm_both[:nao_co, :nao_co] = dma dm_both[nao_co:, nao_co:] = dmb # Compute DFT non-additive potential and energies rho_h2o = eval_rho(h2o, ao_h2o, dmb, xctype='LDA') rho_co = eval_rho(co, ao_co, dma, xctype='LDA') rho_both = eval_rho(system, ao_both, dm_both, xctype='LDA') # Compute all densities on a grid xc_code = 'LDA,VWN' # same as xc_code = 'XC_LDA_X + XC_LDA_C_VWN' t_code = 'XC_LDA_K_TF' excs, vxcs = get_dft_grid_stuff(xc_code, rho_both, rho_co, rho_h2o) ets, vts = get_dft_grid_stuff(t_code, rho_both, rho_co, rho_h2o) vxc_emb = vxcs[0][0] - vxcs[1][0] vt_emb = vts[0][0] - vts[1][0] # Energy functionals: exc_nad = get_nad_energy(grids, excs, rho_both, rho_co, rho_h2o) et_nad = get_nad_energy(grids, ets, rho_both, rho_co, rho_h2o) fock_emb_xc = eval_mat(co, ao_co, grids.weights, rho_co, vxc_emb, xctype='LDA') fock_emb_t = eval_mat(co, ao_co, grids.weights, rho_co, vt_emb, xctype='LDA') # Electrostatic part v_coulomb = get_coulomb(co, h2o, dmb) # Nuclear-electron integrals vAnucB, vBnucA = get_attraction_potential(co, h2o) # Perform the HF-in-HF embedding # Modify Fock matrix focka_ref = scfres2.get_hcore() focka = focka_ref.copy() focka += fock_emb_t + fock_emb_xc + v_coulomb + vAnucB scfres3 = scf.RHF(co) scfres3.conv_tol = 1e-12 scfres3.get_hcore = lambda *args: focka # Re-evaluate the energy scfres3.kernel() # Get density matrix, to only evaluate dma_final = scfres3.make_rdm1() int_ref_xc = np.einsum('ab,ba', fock_emb_xc, dma) int_ref_t = np.einsum('ab,ba', fock_emb_t, dma) rhoArhoB = np.einsum('ab,ba', v_coulomb, dma_final) nucArhoB = np.einsum('ab,ba', vAnucB, dma_final) nucBrhoA = np.einsum('ab,ba', vBnucA, dmb) # Linearization terms int_emb_xc = np.einsum('ab,ba', fock_emb_xc, dma_final) int_emb_t = np.einsum('ab,ba', fock_emb_t, dma_final) deltalin = (int_emb_xc - int_ref_xc) + (int_emb_t - int_ref_t) # Save terms in dictionary embdic = {} embdic['rhoArhoB'] = rhoArhoB embdic['nucArhoB'] = nucArhoB embdic['nucBrhoA'] = nucBrhoA embdic['exc_nad'] = exc_nad embdic['et_nad'] = et_nad embdic['int_ref_xc'] = int_ref_xc embdic['int_ref_t'] = int_ref_t embdic['int_emb_xc'] = int_emb_xc embdic['int_emb_t'] = int_emb_t embdic['deltalin'] = deltalin if return_matrices: matdic = {} matdic['dma'] = dma matdic['dmb'] = dmb matdic['dma_final'] = dma_final matdic['fock_emb_xc'] = fock_emb_xc matdic['fock_emb_t'] = fock_emb_t matdic['v_coulomb'] = v_coulomb matdic['vAnucB'] = vAnucB matdic['vBnucA'] = vBnucA return embdic, matdic else: return embdic
def fast_newton(mf, mo_coeff=None, mo_occ=None, dm0=None, auxbasis=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. ''' 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) mf1 = density_fit(newton(mf), auxbasis) for key in newton_kwargs: setattr(mf1, key, newton_kwargs[key]) if hasattr(mf, 'grids'): import copy 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 if dm0 is not None: mo_coeff, mo_occ = mf1.from_dm(dm0) elif mo_coeff is None or mo_occ is None: if mf.mo_coeff is not None and mf.mo_occ is not None: mo_coeff, mo_occ = mf.mo_coeff, mf.mo_occ else: logger.note( mf, '========================================================') logger.note( mf, 'Generating initial guess with DIIS-SCF for newton solver') logger.note( mf, '========================================================') mf0 = density_fit(mf, auxbasis) mf0.conv_tol = .25 mf0.conv_tol_grad = .5 if mf0.level_shift == 0: mf0.level_shift = .3 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 logger.note(mf, '============================') logger.note(mf, 'Generating initial guess end') logger.note(mf, '============================') mf0 = None 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): from pyscf.lib import logger 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.") return mf.e_tot mf.kernel = mf_kernel return mf
def init_hook(self, mf, **envs): if hasattr(mf, "grid"): self.grids = mf.grids else: self.grids = gen_grid.Grids(mf.mol)
def fast_newton(mf, mo_coeff=None, mo_occ=None, dm0=None, auxbasis=None, dual_basis=None, **newton_kwargs): '''This is a wrap function which combines several operations. This function first setup the initial guess from density fitting calculation then use for Newton solver 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 from pyscf.soscf import newton_ah if auxbasis is None: auxbasis = df.addons.aug_etb_for_dfbasis(mf.mol, 'ahlrichs', beta=2.5) if dual_basis: mf1 = mf.newton() pmol = mf1.mol = newton_ah.project_mol(mf.mol, dual_basis) mf1 = mf1.density_fit(auxbasis) else: mf1 = mf.newton().density_fit(auxbasis) mf1.with_df._compatible_format = False mf1.direct_scf_tol = 1e-7 if getattr(mf, 'grids', None): 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-3) 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 dual_basis: mf0 = copy.copy(mf) mf0.mol = pmol mf0 = mf0.density_fit(auxbasis) else: mf0 = mf.density_fit(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 getattr(mf, 'grids', None): 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() mf1.with_df = mf0.with_df mo_coeff, mo_occ = mf0.mo_coeff, mf0.mo_occ if dual_basis: 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)) mf0 = None 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 emb_potential(mol, nx=80, ny=80, nz=80,option = 1,outfile="emb.cube"): """Calculates the embedding potential and write out in cube format. Args: mol : Mole Molecule to calculate the electron density for. outfile : str Name of Cube file to be written. Kwargs: nx : int Number of grid point divisions in x direction. Note this is function of the molecule's size; a larger molecule will have a coarser representation than a smaller one for the same value. Conflicts to keyword resolution. ny : int Number of grid point divisions in y direction. nz : int Number of grid point divisions in z direction. option: int 1: the complete embedding potential(default) 0: only electrostatic part """ cc = cubegen.Cube(mol, nx, ny, nz,margin=5) points = cc.get_coords() grids = gen_grid.Grids(system) grids.level = 4 grids.build() # Grid for plot rho0 = get_density_from_dm(wrap.mol0, dmA, points) rho1 = get_density_from_dm(wrap.mol1, dmB, points) rho_both = rho0 + rho1 rho1_grid = get_density_from_dm(wrap.mol1, dmB, grids.coords) # write the electron density to a cube file rho = rho_both.reshape(cc.nx,cc.ny,cc.nz) cc.write(rho,'rho.cube', comment='Electron density in real space (e/Bohr^3)') # Coulomb repulsion potential v_coul = coulomb_potential_grid(points, grids.coords, grids.weights, rho1_grid) # Nuclear-electron attraction potential mol1_charges, mol1_coords = get_charges_and_coords(B_mol) v1_nuc0 = np.zeros(rho0.shape) for j, point in enumerate(points): for i in range(len(mol1_charges)): d = np.linalg.norm(point-mol1_coords[i]) if d >= 1e-5: v1_nuc0[j] += - mol1_charges[i]/d # DFT nad potential excs, vxcs = get_dft_grid_stuff(xc_code, rho_both, rho0, rho1) ets, vts = get_dft_grid_stuff(t_code, rho_both, rho0, rho1) vxc_emb = vxcs[0][0] - vxcs[1][0]-vxcs[2][0] vt_emb = vts[0][0] - vts[1][0]- vts[2][0] if option == 1: vemb_tot = v_coul + v1_nuc0 + vxc_emb + vt_emb vemb_tot = vemb_tot.reshape(cc.nx,cc.ny,cc.nz) outfile = 'emb.cube' # Write the potential cc.write(vemb_tot, outfile, 'Molecular embedding electrostatic potential in real space') else: vemb_tot = v_coul + v1_nuc0 vemb_tot = vemb_tot.reshape(cc.nx,cc.ny,cc.nz) outfile = 'emb_elec.cube' # Write the potential cc.write(vemb_tot, outfile, 'Molecular embedding electrostatic potential in real space') return vemb_tot
def test_interpolate_helium(): """Check interpolation for He density.""" # define ta_object dic = os.getenv('FDETADATA') filetraj = os.path.join(dic, 'he_traj.txt') traj = TrajectoryAnalysis(filetraj) box_size = np.array([2, 2, 2]) grid_size = np.array([5, 5, 5]) # Use the mdinterface to create a cubic grid md = MDInterface(traj, box_size, grid_size) # print("Points: \n", md.points) # print(md.npoints*3) grid = np.zeros((md.npoints, 3)) grid = md.pbox.get_grid(grid, False) # Use PySCF to evaluate density from pyscf import gto, scf, dft from pyscf import lib from pyscf.dft.numint import eval_ao, eval_rho, eval_mat from pyscf.dft import gen_grid, libxc mol0 = gto.M(atom="""He 0.000 0.000 0.000""", basis='sto-3g') # Solve HF and get density scfres = scf.RHF(mol0) scfres.conv_tol = 1e-12 scfres.kernel() dm0 = scfres.make_rdm1() # Take only a plane in z=0 subgrid = grid[50:75] ao_mol0 = eval_ao(mol0, subgrid, deriv=0) rho_mol0 = eval_rho(mol0, ao_mol0, dm0, xctype='LDA') rho_plot = rho_mol0.reshape((5, 5)) # Check interpolation in PySCF grid from scipy import interpolate # whole grid ao_all = eval_ao(mol0, grid, deriv=0) rho_all = eval_rho(mol0, ao_all, dm0, xctype='LDA') xs = grid[:, 0] ys = grid[:, 1] zs = grid[:, 2] # print(rho_all.shape) grids = gen_grid.Grids(mol0) grids.level = 4 grids.build() # print(rho_all.shape) # print(grids.coords.shape) xdata = grids.coords[:, 0] ydata = grids.coords[:, 1] zdata = grids.coords[:, 2] # Real values real_ao = eval_ao(mol0, grids.coords, deriv=0) real_rho = eval_rho(mol0, real_ao, dm0, xctype='LDA') # Check with method is the best for Rbf interpolation functions = [ 'multiquadric', 'inverse', 'gaussian', 'linear', 'cubic', 'quintic', 'thin_plate' ] minmax = [] for function in functions: print(function) interpolator = interpolate.Rbf(xs, ys, zs, rho_all, function=function) new_rho = interpolator(xdata, ydata, zdata) minmax.append([ function, min(abs(new_rho - real_rho)), max(abs(new_rho - real_rho)) ]) # fig = plt.figure() # ax = fig.add_subplot(projection='3d') # ax.scatter3D(xdata, ydata, new_rho, c=new_rho, cmap='Greens') # ax.scatter3D(xdata, ydata, real_rho, c=real_rho) # plt.xlim(-1.0, 1.0) # plt.ylim(-1.0, 1.0) # plt.show() # print(minmax) mol1 = gto.M(atom="""He 0.000 0.000 2.500""", basis='sto-3g') # Solve HF and get density scfres1 = scf.RHF(mol1) scfres1.conv_tol = 1e-12 scfres1.kernel() dm1 = scfres1.make_rdm1() # whole grid ao_all1 = eval_ao(mol1, grid, deriv=0) rho_all1 = eval_rho(mol1, ao_all1, dm1, xctype='LDA') # Real values real_ao1 = eval_ao(mol1, grids.coords, deriv=0) real_rho1 = eval_rho(mol1, real_ao1, dm1, xctype='LDA') minmax1 = [] for function in functions: interpolator = interpolate.Rbf(xs, ys, zs, rho_all1, function=function) new_rho1 = interpolator(xdata, ydata, zdata) minmax1.append([ function, min(abs(new_rho1 - real_rho1)), max(abs(new_rho1 - real_rho1)) ]) p = np.where(abs(new_rho1 - real_rho1) == minmax1[-1][2])