RotationalGTensor) if __name__ == '__main__': from pyscf import lib from pyscf import gto from pyscf import dft mol = gto.Mole() mol.verbose = 7 mol.output = '/dev/null' mol.atom = '''h , 0. 0. .917 F , 0. 0. 0. ''' mol.basis = 'ccpvdz' mol.build() mf = dft.UKS(mol).run(xc='b3lyp') rotg = mf.RotationalGTensor() m = rotg.kernel() print(m[0, 0] - 0.6944660741142765) rotg.gauge_orig = (0, 0, .1) m = rotg.kernel() print(m[0, 0] - 0.7362841753490392) mol.atom = '''C , 0. 0. 0. O , 0. 0. 1.1283 ''' mol.basis = 'ccpvdz' mol.build() mf = dft.UKS(mol).run(xc='bp86') rotg = RotationalGTensor(mf)
def UKS(mol, *args): from pyscf import dft return dft.UKS(mol)
def test_convert(self): rhf = scf.RHF(mol) uhf = scf.UHF(mol) ghf = scf.GHF(mol) rks = dft.RKS(mol) uks = dft.UKS(mol) gks = dft.GKS(mol) dhf = scf.DHF(mol) dks = dft.DKS(mol) udhf = scf.dhf.UDHF(mol) udks = dft.dks.UDKS(mol) self.assertTrue(isinstance(rhf.to_rhf(), scf.rhf.RHF)) self.assertTrue(isinstance(rhf.to_uhf(), scf.uhf.UHF)) self.assertTrue(isinstance(rhf.to_ghf(), scf.ghf.GHF)) self.assertTrue(isinstance(rhf.to_rks(), dft.rks.RKS)) self.assertTrue(isinstance(rhf.to_uks(), dft.uks.UKS)) self.assertTrue(isinstance(rhf.to_gks(), dft.gks.GKS)) self.assertTrue(isinstance(rks.to_rhf(), scf.rhf.RHF)) self.assertTrue(isinstance(rks.to_uhf(), scf.uhf.UHF)) self.assertTrue(isinstance(rks.to_ghf(), scf.ghf.GHF)) self.assertTrue(isinstance(rks.to_rks('pbe'), dft.rks.RKS)) self.assertTrue(isinstance(rks.to_uks('pbe'), dft.uks.UKS)) self.assertTrue(isinstance(rks.to_gks('pbe'), dft.gks.GKS)) self.assertTrue(isinstance(uhf.to_rhf(), scf.rhf.RHF)) self.assertTrue(isinstance(uhf.to_uhf(), scf.uhf.UHF)) self.assertTrue(isinstance(uhf.to_ghf(), scf.ghf.GHF)) self.assertTrue(isinstance(uhf.to_rks(), dft.rks.RKS)) self.assertTrue(isinstance(uhf.to_uks(), dft.uks.UKS)) self.assertTrue(isinstance(uhf.to_gks(), dft.gks.GKS)) self.assertTrue(isinstance(rks.to_rhf(), scf.rhf.RHF)) self.assertTrue(isinstance(rks.to_uhf(), scf.uhf.UHF)) self.assertTrue(isinstance(rks.to_ghf(), scf.ghf.GHF)) self.assertTrue(isinstance(uks.to_rks('pbe'), dft.rks.RKS)) self.assertTrue(isinstance(uks.to_uks('pbe'), dft.uks.UKS)) self.assertTrue(isinstance(uks.to_gks('pbe'), dft.gks.GKS)) #self.assertTrue(isinstance(ghf.to_rhf(), scf.rhf.RHF)) #self.assertTrue(isinstance(ghf.to_uhf(), scf.uhf.UHF)) self.assertTrue(isinstance(ghf.to_ghf(), scf.ghf.GHF)) #self.assertTrue(isinstance(ghf.to_rks(), dft.rks.RKS)) #self.assertTrue(isinstance(ghf.to_uks(), dft.uks.UKS)) self.assertTrue(isinstance(ghf.to_gks(), dft.gks.GKS)) #self.assertTrue(isinstance(gks.to_rhf(), scf.rhf.RHF)) #self.assertTrue(isinstance(gks.to_uhf(), scf.uhf.UHF)) self.assertTrue(isinstance(gks.to_ghf(), scf.ghf.GHF)) #self.assertTrue(isinstance(gks.to_rks('pbe'), dft.rks.RKS)) #self.assertTrue(isinstance(gks.to_uks('pbe'), dft.uks.UKS)) self.assertTrue(isinstance(gks.to_gks('pbe'), dft.gks.GKS)) self.assertRaises(RuntimeError, dhf.to_rhf) self.assertRaises(RuntimeError, dhf.to_uhf) self.assertRaises(RuntimeError, dhf.to_ghf) self.assertRaises(RuntimeError, dks.to_rks) self.assertRaises(RuntimeError, dks.to_uks) self.assertRaises(RuntimeError, dks.to_gks) if scf.dhf.zquatev is not None: self.assertTrue(isinstance(dhf.to_dhf(), scf.dhf.RDHF)) self.assertTrue(isinstance(dhf.to_dks(), dft.dks.RDKS)) self.assertTrue(isinstance(dks.to_dhf(), scf.dhf.RDHF)) self.assertTrue(isinstance(dks.to_dks('pbe'), dft.dks.RDKS)) self.assertTrue(isinstance(dhf.to_dhf(), scf.dhf.DHF)) self.assertTrue(isinstance(dhf.to_dks(), dft.dks.DKS)) self.assertTrue(isinstance(dks.to_dhf(), scf.dhf.DHF)) self.assertTrue(isinstance(dks.to_dks('pbe'), dft.dks.DKS)) self.assertTrue(isinstance(udhf.to_dhf(), scf.dhf.DHF)) self.assertTrue(isinstance(udhf.to_dks(), dft.dks.DKS)) self.assertTrue(isinstance(udks.to_dhf(), scf.dhf.DHF)) self.assertTrue(isinstance(udks.to_dks('pbe'), dft.dks.DKS))
from pyscf import tddft mol = gto.Mole() mol.verbose = 0 mol.output = None mol.atom = [ ['H', (0., 0., 1.804)], ['F', (0., 0., 0.)], ] mol.unit = 'B' mol.basis = '631g' mol.charge = -2 mol.spin = 2 mol.build() mf = dft.UKS(mol).set(conv_tol=1e-14) mf.xc = 'LDA,' mf.grids.prune = False mf.kernel() td = tddft.TDDFT(mf) td.nstates = 3 e, z = td.kernel() tdg = td.Gradients() g1 = tdg.kernel(state=3) print(g1) # [[ 0 0 -1.72842011e-01] # [ 0 0 1.72846027e-01]] td_solver = td.as_scanner() e1 = td_solver(mol.set_geom_('H 0 0 1.805; F 0 0 0', unit='B')) e2 = td_solver(mol.set_geom_('H 0 0 1.803; F 0 0 0', unit='B'))
Grad = Gradients if __name__ == '__main__': from pyscf import gto from pyscf import dft mol = gto.Mole() mol.atom = [['O', (0., 0., 0.)], [1, (0., -0.757, 0.587)], [1, (0., 0.757, 0.587)]] mol.basis = '631g' mol.charge = 1 mol.spin = 1 mol.build() mf = dft.UKS(mol).density_fit() mf.conv_tol = 1e-12 e0 = mf.scf() g = Gradients(mf).set(auxbasis_response=False) print(lib.finger(g.kernel()) - -0.12092643506961044) g = Gradients(mf) print(lib.finger(g.kernel()) - -0.12092884149543644) # O -0.0000000000 0.0000000000 0.0533109212 # H -0.0000000000 0.0675360271 -0.0266615265 # H 0.0000000000 -0.0675360271 -0.0266615265 g.grid_response = True # O -0.0000000000 0.0000000000 0.0533189584 # H -0.0000000000 0.0675362403 -0.0266594792 # H 0.0000000000 -0.0675362403 -0.0266594792 print(lib.finger(g.kernel()) - -0.12093220332146028)
pred_exc = model(x) exc = pred_exc.data[:, 0].numpy() #+0.015471944-0.002533411+0.001574637 eneden = torch.dot(pred_exc[:, 0], x[:, 0] + x[:, 1]) eneden.backward() grad = x.grad.data.numpy() if spin != 0: vlapl = np.zeros((N, 2)) vrho = np.hstack((grad[:, 0].reshape((-1, 1)), grad[:, 1].reshape( (-1, 1)))) vgamma = np.hstack((grad[:, 2].reshape((-1, 1)), grad[:, 3].reshape( (-1, 1)), grad[:, 4].reshape((-1, 1)))) else: vlapl = np.zeros(N) vrho = (grad[:, 0] + grad[:, 1]) / 2 vgamma = (grad[:, 2] + grad[:, 4] + grad[:, 3]) / 4 vxc = (vrho, vgamma, None, None) return exc, vxc, None, None # DFT calculation # if mol.spin == 0: mfl = dft.RKS(mol) else: mfl = dft.UKS(mol) mfl = mfl.define_xc_(eval_xc, 'GGA') mfl.kernel()
mol = gto.Mole() mol.verbose = 5 mol.output = '/dev/null' mol.atom = [ ["O" , (0. , 0. , 0.)], [1 , (0. , -0.757 , 0.587)], [1 , (0. , 0.757 , 0.587)] ] mol.spin = 2 mol.basis = '631g' mol.build() mf = scf.UHF(mol).run() td_hf = tdscf.TDHF(mf).run() mf_lda = dft.UKS(mol).set(xc='lda', conv_tol=1e-12) mf_lda.grids.prune = None mf_lda = mf_lda.newton().run() mf_bp86 = dft.UKS(mol).set(xc='b88,p86', conv_tol=1e-12) mf_bp86.grids.prune = None mf_bp86 = mf_bp86.newton().run() mf_b3lyp = dft.UKS(mol).set(xc='b3lyp', conv_tol=1e-12) mf_b3lyp.grids.prune = None mf_b3lyp = mf_b3lyp.newton().run() def diagonalize(a, b, nroots=4): a_aa, a_ab, a_bb = a b_aa, b_ab, b_bb = b nocc_a, nvir_a, nocc_b, nvir_b = a_ab.shape a_aa = a_aa.reshape((nocc_a*nvir_a,nocc_a*nvir_a)) a_ab = a_ab.reshape((nocc_a*nvir_a,nocc_b*nvir_b))
ls_vert.fcisolver = fci.solver(mf.mol, singlet=True) els_vert = ls_vert.kernel()[0] ls_rel = mcscf.CASSCF(mf, 4, (2, 2)) ls_rel.fcisolver = fci.solver(mf.mol, singlet=True) els_rel = ls_rel.kernel()[0] print("CASSCF high-spin energy: {:.8f}".format(ehs)) print("CASSCF (vertical) low-spin energy: {:.8f}".format(els_vert)) print("CASSCF (relaxed) low-spin energy: {:.8f}".format(els_rel)) print("CASSCF vertical excitation energy (eV): {:.8f}".format( 27.2114 * (els_vert - ehs))) print("CASSCF relaxed excitation energy (eV): {:.8f}".format(27.2114 * (els_rel - ehs))) ks = dft.UKS(mol) ks.xc = 'pbe' ks.grids.level = 9 ot = otfnal.transfnal(ks) els_vert = mcpdft.kernel(ls_vert, ot) els_rel = mcpdft.kernel(ls_rel, ot) ehs = mcpdft.kernel(hs, ot) print("MC-PDFT (tPBE) high-spin energy: {:.8f}".format(ehs)) print("MC-PDFT (tPBE) (vertical) low-spin energy: {:.8f}".format(els_vert)) print("MC-PDFT (tPBE) (relaxed) low-spin energy: {:.8f}".format(els_rel)) print("MC-PDFT (tPBE) vertical excitation energy (eV): {:.8f}".format( 27.2114 * (els_vert - ehs))) print("MC-PDFT (tPBE) relaxed excitation energy (eV): {:.8f}".format( 27.2114 * (els_rel - ehs)))
# # RKS # mf = mpi_dft.RKS(mol) mf.xc = 'b3lyp' vxc = mf.get_veff(mol, dm) mf.run() mf0 = dft.RKS(mol) mf0.xc = 'b3lyp' vxc0 = mf0.get_veff(mol, dm) mf0.run() print(abs(vxc0 - vxc).max()) # # UKS # dm = numpy.random.random((2, nao, nao)) dm = dm + dm.transpose(0, 2, 1) mol.spin = 2 mf = mpi_dft.UKS(mol) mf.xc = 'b3lyp' vxc = mf.get_veff(mol, dm) mf.run() mf0 = dft.UKS(mol) mf0.xc = 'b3lyp' vxc0 = mf0.get_veff(mol, dm) mf0.run() print(abs(vxc0 - vxc).max())
from flosic_scf import FLOSIC b = 'sto6g' spin = 0 charge = 0 mol = gto.M(atom=CH3SH, basis=b, spin=spin, charge=charge) grid_level = 5 mol.verbose = 4 mol.max_memory = 2000 mol.build() xc = 'LDA,PW' # quick dft calculation mdft = dft.UKS(mol) mdft.xc = xc mdft.kernel() # build FLOSIC object mflosic = FLOSIC(mol, xc=xc, fod1=fodup, fod2=foddn, grid_level=grid_level, init_dm=mdft.make_rdm1()) mflosic.max_cycle = 40 mflosic.conv_tol = 1e-5 # just for testing calc = BasicFLOSICC(atoms=fod, mf=mflosic) #print(fod.get_potential_energy())
gobj.so_eff_charge = True gobj.kernel() # # Attribute gauge_orig controls whether to use GIAO. GIAO is used by default. # gobj.gauge_orig = mol.atom_coord(1) # on N atom gobj.dia_soc2e = False gobj.para_soc2e = True gobj.so_eff_charge = False gobj.kernel() # # In pure DFT (LDA, GGA), CPSCF has no effects. Setting cphf=False can switch # off CPSCF. # mf = dft.UKS(mol).set(xc='bp86').run() gobj = gtensor.uks.GTensor(mf).set(verbose=4) gobj.cphf = False gobj.gauge_orig = (0, 0, 0) gobj.kernel() # # Only UHF and UKS are supported in g-tensor module. ROHF and ROKS need to be # transfered to UHF or UKS before calling g-tensor methods. # mf = scf.RKS(mol).run() mf = scf.convert_to_uhf(mf) gobj = gtensor.uhf.GTensor(mf).set(verbose=4) print(gobj.kernel())
''' from pyscf import gto, scf, dft mol = gto.Mole() mol.verbose = 1 #mol.output ='mom_DeltaSCF.out' mol.atom = [["O", (0., 0., 0.)], ["H", (0., -0.757, 0.587)], ["H", (0., 0.757, 0.587)]] mol.basis = { "H": '6-31g', "O": '6-31g', } mol.build() a = dft.UKS(mol) a.xc = 'b3lyp' # Use chkfile to store ground state information and start excited state # caculation from these information directly #mf.chkfile='ground.chkfile' a.scf() # Read MO coefficients and occpuation number from chkfile #mo0 = scf.chkfile.load('ground.chkfile', 'scf/mo_coeff') #occ = scf.chkfile.load('ground.chkfile', 'scf/mo_occ') mo0 = a.mo_coeff occ = a.mo_occ # Assigned initial occupation pattern occ[0][ 4] = 0 # this excited state is originated from H**O(alpha) -> LUMO(alpha)
charge = 0 b = 'cc-pvqz' # As we will later do exchange-correlation and exchange only calculation it makes sense to define both functionals here. xc = 'LDA,PW' x = 'LDA,' # Now we can build the mole object. mol = gto.M(atom=ase2pyscf(nuclei), basis=b, spin=spin, charge=charge) # The next part is the definition of the calculator objects. # For both xc and x we create a separate calculator object. dftx = dft.UKS(mol) dftx.xc = x dftxc = dft.UKS(mol) dftxc.xc = xc sicx = FLOSIC(mol, xc=x, fod1=fod1, fod2=fod2) sicxc = FLOSIC(mol, xc=xc, fod1=fod1, fod2=fod2) # Now we need to do the ground state calculations. etot_dftx = dftx.kernel() etot_dftxc = dftxc.kernel() etot_sicx = sicx.kernel() etot_sicxc = sicxc.kernel() # Then we can access the xc energies.
def run_scf_for_mol(atom, charge, spin, xc, basis, xc_fun=None, hybrid_coeff=None, rsh_params=None, conv_tol=None, conv_tol_grad=None, use_sg1_prune_for_nlc=True, verbosity=4, max_memory=4000): """Performs SCF calculation for a single molecule. Args: atom: String, the atomic structure. charge: Integer, the total charge of molecule. spin: Integer, the difference of spin up and spin down electron numbers. xc: String, the XC functional name. basis: String, the GTO basis. xc_fun: Function, custom XC functional. If xcfun is specified, the eval_xc method in PySCF will be overridden, and the argument 'xc' will only be used to determine VV10 NLC. hybrid_coeff: Float, the fraction of exact exchange for custom global hybrid functional. rsh_params: Tuple of (float, float, float), RSH parameters for custom range-separated hybrid functional. conv_tol: Float, the convergence threshold of total energy. If not specified, the PySCF default value 1e-9 au is used. conv_tol_grad: Float, the convergence threshold of orbital gradients. If not specified, the PySCF default value of sqrt(conv_tol) is used. use_sg1_prune_for_nlc: Boolean, whether use SG1 prune for NLC calculation. verbosity: Integer, the verbosity level for PySCF. max_memory: Float, the maximum memory in MB for PySCF. Returns: Dict, the results of the SCF calculation. Contains following keys: * Etot: Float, the DFT total energy. * Exc: Float, the exchange-correlation energy. * Exx: Float, the exact-exchange energy (equal to Exc if xc == 'HF'). * rho: Float numpy array with shape (6, num_grids) for spin unpolarized case and (2, 6, num_grids) for spin polarized case, the density and its gradients. For spin polarized case, the first dimension represent spin index. The dimension with size 6 represents (density, gradient_x, gradient_y, gradient_z, laplacian, tau). * weights: Float numpy array with shape (num_grids,), the weights for numerical integration. * converged: Boolean, whether the SCF calculation is converged. * time: Float, the walltime elapsed for the calculation. """ start = time.time() logging.info('Construct molecule.') mol = gto.M( atom=atom, basis=basis, charge=charge, spin=spin, verbose=verbosity, max_memory=max_memory ) logging.info('Construct KS calculation.') if spin == 0: ks = dft.RKS(mol) else: ks = dft.UKS(mol) ks.xc = xc if xc_fun is not None: logging.info('Use Custom XC: %s', xc_fun) logging.info('hybrid_coeff = %s, rsh_params = %s', hybrid_coeff, rsh_params) ks.define_xc_(xc_fun, xctype='MGGA', hyb=hybrid_coeff, rsh=rsh_params) if xc.upper() in dft.libxc.VV10_XC: logging.info('Use VV10 NLC.') ks.nlc = 'VV10' if use_sg1_prune_for_nlc: # NOTE(htm): SG1 prune can be used to reduce the computational cost of # VV10 NLC. The use of SG1 prune has very little effect on the resulting # XC energy. SG1 prune is used in PySCF's example # pyscf/examples/dft/33-nlc_functionals.py and is also used in paper # 10.1080/00268976.2017.1333644. Note that SG1 prune in PySCF is not # available for some elements appeared in the MCGDB84 database. ks.nlcgrids.prune = dft.gen_grid.sg1_prune if xc_fun is not None: # NOTE(htm): It is necessary to override ks._numint._xc_type method to # let PySCF correctly use a custom XC functional with NLC. Also, note that # ks.xc is used to determine NLC parameters. ks._numint._xc_type = lambda code: 'NLC' if 'VV10' in code else 'MGGA' # pylint: disable=protected-access if conv_tol is not None: ks.conv_tol = conv_tol if conv_tol_grad is not None: ks.conv_tol_grad = conv_tol_grad logging.info('Perform SCF calculation.') ks.kernel() logging.info('Compute rho and derivatives.') ao = dft.numint.eval_ao(ks.mol, coords=ks.grids.coords, deriv=2) if spin == 0: rho = dft.numint.eval_rho2( ks.mol, ao, mo_coeff=ks.mo_coeff, mo_occ=ks.mo_occ, xctype='MGGA') else: rhoa = dft.numint.eval_rho2( ks.mol, ao, mo_coeff=ks.mo_coeff[0], mo_occ=ks.mo_occ[0], xctype='MGGA') rhob = dft.numint.eval_rho2( ks.mol, ao, mo_coeff=ks.mo_coeff[1], mo_occ=ks.mo_occ[1], xctype='MGGA') rho = np.array([rhoa, rhob]) logging.info('Compute exact exchange energy.') dm = ks.make_rdm1() vk = ks.get_k() if spin == 0: e_xx = -np.einsum('ij,ji', dm, vk) * .5 * .5 else: e_xx = -(np.einsum('ij,ji', dm[0], vk[0]) + np.einsum('ij,ji', dm[1], vk[1])) * .5 if xc_fun is None: omega = dft.libxc.rsh_coeff(ks.xc)[0] else: omega = rsh_params[0] if abs(omega) > 1e-10: vklr = dft.rks._get_k_lr(mol, dm, omega=omega) # pylint: disable=protected-access # NOTE(htm): in PySCF v1.5a, _get_k_lr is protected. In PySCF >= 1.7.0 # one can use vklr = ks.get_k(omega=omega) if spin == 0: e_xxlr = - np.einsum('ij,ji', dm, vklr) * .5 * .5 else: e_xxlr = - (np.einsum('ij,ji', dm[0], vklr[0]) + np.einsum('ij,ji', dm[1], vklr[1])) * .5 else: e_xxlr = 0. if ks.nlc: logging.info('Compute VV10 nonlocal correlation energy.') _, e_nlc, _ = ks._numint.nr_rks( # pylint: disable=protected-access # NOTE(htm): in PySCF v1.5a, dft.numint.nr_rks takes an _NumInt instance # as the first argument. Therefore it is difficult to circumvent the # access to protected attributes. In PySCF >= 1.7.0, NumInt is no longer # protected. mol=mol, grids=ks.nlcgrids, xc_code=ks.xc + '__' + ks.nlc, dms=(dm if spin == 0 else dm[0] + dm[1])) else: e_nlc = 0. results = { 'Etot': ks.e_tot, 'Exc': ks.get_veff(mol, dm=ks.make_rdm1()).exc, 'Exx': e_xx, 'Exxlr': e_xxlr, 'Enlc': e_nlc, 'rho': rho, 'weights': ks.grids.weights, 'converged': ks.converged, 'time': time.time() - start, } logging.info('SCF finished. Results: %s', results) return results
''' from pyscf.prop.polarizability.uhf import \ (polarizability, hyper_polarizability, polarizability_with_freq, Polarizability) if __name__ == '__main__': import numpy from pyscf import gto from pyscf import dft mol = gto.M(atom='''O 0. 0. 0. H 0. -0.757 0.587 H 0. 0.757 0.587''', basis='6-31g') mf = dft.UKS(mol).run(xc='b3lyp', conv_tol=1e-14) polar = Polarizability(mf).polarizability() hpol = Polarizability(mf).hyper_polarizability() print(polar) mf.verbose = 0 charges = mol.atom_charges() coords = mol.atom_coords() charge_center = numpy.einsum('i,ix->x', charges, coords) / charges.sum() with mol.with_common_orig(charge_center): ao_dip = mol.intor_symmetric('int1e_r', comp=3) h1 = mf.get_hcore() def apply_E(E): mf.get_hcore = lambda *args, **kwargs: h1 + numpy.einsum('x,xij->ij', E, ao_dip) mf.run(conv_tol=1e-14) return mf.dip_moment(mol, mf.make_rdm1(), unit='AU', verbose=0)
from pyscf.grad import tduks as tduks_grad mol = gto.Mole() mol.verbose = 5 mol.output = '/dev/null' mol.atom = [ ['H', (0., 0., 1.804)], ['F', (0., 0., 0.)], ] mol.unit = 'B' mol.charge = 2 mol.spin = 2 mol.basis = '631g' mol.build() pmol = mol.copy() mf_lda = dft.UKS(mol).set(xc='LDA,', conv_tol=1e-12) mf_lda.kernel() mf_gga = dft.UKS(mol).set(xc='b88,', conv_tol=1e-12) mf_gga.kernel() def tearDownModule(): global mol, pmol mol.stdout.close() del mol, pmol class KnownValues(unittest.TestCase): def test_tda_lda(self): td = tdscf.TDA(mf_lda).run(nstates=3) tdg = td.nuc_grad_method()
def do_scf(inp): '''Do the requested SCF.''' from pyscf import gto, scf, dft, cc, fci, ci, ao2mo, mcscf, mrpt, lib, mp, tdscf from pyscf.cc import ccsd_t, uccsd_t import numpy as np from .fcidump import fcidump # sort out the method mol = inp.mol method = inp.scf.method.lower() # UHF if method == 'uhf': ehf, mSCF = do_hf(inp, unrestricted=True) print_energy('UHF', ehf) if inp.scf.exci is not None: inp.timer.start('TDHF') mtd = do_TDDFT(inp, mSCF) inp.timer.end('TDHF') # RHF elif method in ('rhf', 'hf'): ehf, mSCF = do_hf(inp) print_energy('RHF', ehf) if inp.scf.exci is not None: inp.timer.start('TDHF') mtd = do_TDDFT(inp, mSCF) inp.timer.end('TDHF') # CCSD and CCSD(T) elif method in ('ccsd', 'ccsd(t)', 'uccsd', 'uccsd(t)', 'eomccsd'): if 'u' in method: ehf, tSCF = do_hf(inp, unrestricted=True) print_energy('UHF', ehf) else: ehf, tSCF = do_hf(inp) print_energy('RHF', ehf) inp.timer.start('ccsd') frozen = 0 if inp.scf.freeze is not None: frozen = inp.scf.freeze if 'u' in method: mSCF = cc.UCCSD(tSCF, frozen=frozen) else: mSCF = cc.CCSD(tSCF, frozen=frozen) mSCF.max_cycle = inp.scf.maxiter eccsd, t1, t2 = mSCF.kernel() print_energy('CCSD', ehf + eccsd) inp.timer.end('ccsd') if method == 'eomccsd': inp.timer.start('eomccsd') ee = mSCF.eomee_ccsd_singlet(nroots=4)[0] inp.timer.end('eomccsd') for i in range(len(ee)): print_energy('EOM-CCSD {0} (eV)'.format(i+1), ee[i] * 27.2114) if method in ('ccsd(t)', 'uccsd(t)'): inp.timer.start('ccsd(t)') eris = mSCF.ao2mo() if method == 'ccsd(t)': e3 = ccsd_t.kernel(mSCF, eris) else: e3 = uccsd_t.kernel(mSCF, eris) print_energy('CCSD(T)', ehf + eccsd + e3) inp.timer.end('ccsd(t)') # MP2 elif method == 'mp2': ehf, tSCF = do_hf(inp) print_energy('RHF', ehf) inp.timer.start('mp2') frozen = 0 if inp.scf.freeze is not None: frozen = inp.scf.freeze mSCF = mp.MP2(tSCF, frozen=frozen) emp2, t2 = mSCF.kernel() print_energy('MP2', ehf+emp2) inp.timer.end('mp2') # CISD elif method == 'cisd' or method == 'cisd(q)': ehf, tSCF = do_hf(inp) print_energy('RHF', ehf) inp.timer.start('cisd') frozen = 0 if inp.scf.freeze is not None: frozen = inp.scf.freeze mSCF = ci.CISD(tSCF, frozen=frozen) ecisd = mSCF.kernel()[0] print_energy('CISD', ehf + ecisd) inp.timer.end('cisd') # perform Davison quadruples correction c0 = np.max(np.abs(mSCF.ci)) c02 = c0**2 ne = mSCF.mol.nelectron eq = ( 1.0 - c02 ) * ecisd print_energy('CISD(Q) Davidson', ehf + ecisd + eq) eq = ( 1.0 - c02 ) / c02 * ecisd print_energy('CISD(Q) Renomalized-Davidson', ehf + ecisd + eq) eq = ( 1.0 - c02 ) / ( 2.0 * c02 - 1.0 ) * ecisd print_energy('CISD(Q) Davison-Silver', ehf + ecisd + eq) eq = (( 2.0 * c02 ) / ((2.0*c02-1.0)*(1.0 + np.sqrt(1.0 + (8.0*c02*(1.0-c02)) / ( ne * (2.0*c02-1.0)**2 )))) - 1.0 ) * ecisd print_energy('CISD(Q) PC', ehf + ecisd + eq) eq = ( 1.0 - c02 ) / c02 * ((ne-2)*(ne-3.0)) / (ne*(ne-1.0)) * ecisd print_energy('CISD(Q) MC', ehf + ecisd + eq) if ne > 2: eq = ( 2.0 - c02 ) / (2.0 * (ne-1.0)/(ne-2.0) * c02 - 1.0) else: eq = 0.0 print_energy('CISD(Q) DD', ehf + ecisd + eq) # UKS elif method in ('uks' or 'udft'): inp.timer.start('uks') inp.timer.start('grids') grids = dft.gen_grid.Grids(mol) grids.level = inp.scf.grid grids.build() inp.timer.end('grids') mSCF = dft.UKS(mol) mSCF.grids = grids mSCF.xc = inp.scf.xc mSCF.conv_tol = inp.scf.conv mSCF.conv_tol_grad = inp.scf.grad mSCF.max_cycle = inp.scf.maxiter mSCF.init_guess = inp.scf.guess mSCF.small_rho_cutoff = 1e-20 eks = mSCF.kernel() print_energy('UKS', eks) inp.timer.end('uks') if inp.scf.exci is not None: inp.timer.start('TDDFT') mtd = do_TDDFT(inp, mSCF) inp.timer.end('TDDFT') # RKS elif method in ('rks', 'ks', 'rdft', 'dft'): inp.timer.start('ks') inp.timer.start('grids') grids = dft.gen_grid.Grids(mol) grids.level = inp.scf.grid grids.build() inp.timer.end('grids') if mol.nelectron%2 == 0: mSCF = dft.RKS(mol) else: mSCF = dft.ROKS(mol) mSCF.grids = grids mSCF.xc = inp.scf.xc mSCF.conv_tol = inp.scf.conv mSCF.conv_tol_grad = inp.scf.grad mSCF.max_cycle = inp.scf.maxiter mSCF.init_guess = inp.scf.guess mSCF.small_rho_cutoff = 1e-20 mSCF.damp = inp.scf.damp mSCF.level_shift = inp.scf.shift eks = mSCF.kernel() print_energy('RKS', eks) inp.timer.end('ks') if inp.scf.exci is not None: inp.timer.start('TDDFT') mtd = do_TDDFT(inp, mSCF) inp.timer.end('TDDFT') # Unrestricted FCI elif method == 'ufci': ehf, mSCF = do_hf(inp, unrestricted=True) print_energy('UHF', ehf) inp.timer.start('fci') cis = fci.direct_uhf.FCISolver(mol) norb = mSCF.mo_energy[0].size nea = (mol.nelectron+mol.spin) // 2 neb = (mol.nelectron-mol.spin) // 2 nelec = (nea, neb) mo_a = mSCF.mo_coeff[0] mo_b = mSCF.mo_coeff[1] h1e_a = reduce(np.dot, (mo_a.T, mSCF.get_hcore(), mo_a)) h1e_b = reduce(np.dot, (mo_b.T, mSCF.get_hcore(), mo_b)) g2e_aa = ao2mo.incore.general(mSCF._eri, (mo_a,)*4, compact=False) g2e_aa = g2e_aa.reshape(norb,norb,norb,norb) g2e_ab = ao2mo.incore.general(mSCF._eri, (mo_a,mo_a,mo_b,mo_b), compact=False) g2e_ab = g2e_ab.reshape(norb,norb,norb,norb) g2e_bb = ao2mo.incore.general(mSCF._eri, (mo_b,)*4, compact=False) g2e_bb = g2e_bb.reshape(norb,norb,norb,norb) h1e = (h1e_a, h1e_b) eri = (g2e_aa, g2e_ab, g2e_bb) eci = fci.direct_uhf.kernel(h1e, eri, norb, nelec)[0] print_energy('FCI', eci) inp.timer.end('fci') # FCI elif method in ('fci'): ehf, mSCF = do_hf(inp) print_energy('RHF', ehf) inp.timer.start('fci') if inp.scf.freeze is None: mCI = fci.FCI(mSCF) if inp.scf.roots is not None: mCI.nroots = inp.scf.roots mCI.kernel()[0] eci = mCI.eci else: nel = mol.nelectron - inp.scf.freeze * 2 ncas = mol.nao_nr() - inp.scf.freeze if mol.spin == 0: nelecas = nel mCI = mcscf.CASCI(mSCF, ncas, nelecas) mCI.fcisolver = fci.solver(mol) else: if mol.spin%2 == 0: nelecas = (nel//2+mol.spin//2, nel//2-mol.spin//2) else: nelecas = (nel//2+mol.spin//2+1, nel//2-mol.spin//2) mCI = mcscf.CASCI(mSCF, ncas, nelecas) mCI.fcisolver = fci.direct_spin1.FCISolver(mol) eci = mCI.kernel()[0] dm = mCI.make_rdm1() dip = mSCF.dip_moment(dm=dm) if inp.scf.roots is None: print_energy('FCI', eci) else: for i in range(inp.scf.roots): print_energy('FCI {0}'.format(i), eci[i]) inp.timer.end('fci') # CASCI elif method == 'casci': if inp.scf.cas is None and inp.scf.casorb is None: print ('ERROR: Must specify CAS space or CASORB') return inp ehf, mSCF = do_hf(inp) print_energy('RHF', ehf) # get cas space if inp.scf.cas is not None: if mol.spin == 0: nelecas = inp.scf.cas[0] else: nelecas = (inp.scf.cas[0]//2 + mol.spin//2, inp.scf.cas[0]//2 - mol.spin//2) ncasorb = inp.scf.cas[1] elif inp.scf.casorb is not None: ncasorb = len(inp.scf.casorb) nelecas = int(np.sum(mSCF.mo_occ[inp.scf.casorb])) if inp.scf.casspin is not None: nelecas = (nelecas//2 + inp.scf.casspin//2, nelecas//2 - inp.scf.casspin//2) inp.timer.start('casci') mCI = mcscf.CASCI(mSCF, ncasorb, nelecas) if inp.scf.casorb is not None: mo = mcscf.addons.sort_mo(mCI, np.copy(mSCF.mo_coeff), inp.scf.casorb, 0) else: mo = np.copy(mSCF.mo_coeff) eci = mCI.kernel(mo)[0] print_energy('CASCI', eci) inp.timer.end('casci') # CASSCF elif method == 'casscf' or method == 'ucasscf': if inp.scf.cas is None and inp.scf.casorb is None: print ('ERROR: Must specify CAS space or CASORB') return inp lunrestricted = (method == 'ucasscf') ehf, mSCF = do_hf(inp, unrestricted=lunrestricted) print_energy('HF', ehf) # get cas space if inp.scf.cas is not None: if mol.spin == 0: nelecas = inp.scf.cas[0] else: nelecas = (inp.scf.cas[0]//2 + mol.spin//2, inp.scf.cas[0]//2 - mol.spin//2) ncasorb = inp.scf.cas[1] elif inp.scf.casorb is not None: ncasorb = len(inp.scf.casorb) nelecas = int(np.sum(mSCF.mo_occ[inp.scf.casorb])) if inp.scf.casspin is not None: nelecas = (nelecas//2 + inp.scf.casspin//2, nelecas//2 - inp.scf.casspin//2) inp.timer.start('casscf') mCI = mcscf.CASSCF(mSCF, ncasorb, nelecas) if inp.scf.casorb is not None: mo = mcscf.addons.sort_mo(mCI, np.copy(mSCF.mo_coeff), inp.scf.casorb, 0) else: mo = np.copy(mSCF.mo_coeff) eci = mCI.kernel(mo)[0] print_energy('CASSCF', eci) inp.timer.end('casscf') # NEVPT2 elif method == 'nevpt2' or method == 'unevpt2': if inp.scf.cas is None and inp.scf.casorb is None: print ('ERROR: Must specify CAS space or CASORB') return inp ehf, mSCF = do_hf(inp) print_energy('RHF', ehf) inp.timer.start('casscf') # get cas space if inp.scf.cas is not None: if mol.spin == 0: nelecas = inp.scf.cas[0] else: nelecas = (inp.scf.cas[0]//2 + mol.spin//2, inp.scf.cas[0]//2 - mol.spin//2) ncasorb = inp.scf.cas[1] elif inp.scf.casorb is not None: ncasorb = len(inp.scf.casorb) nelecas = int(np.sum(mSCF.mo_occ[inp.scf.casorb])) if inp.scf.casspin is not None: nelecas = (nelecas//2 + inp.scf.casspin//2, nelecas//2 - inp.scf.casspin//2) mCI = mcscf.CASSCF(mSCF, ncasorb, nelecas, frozen=inp.scf.freeze) if inp.scf.casorb is not None: mo = mcscf.addons.sort_mo(mCI, np.copy(mSCF.mo_coeff), inp.scf.casorb, 0) else: mo = np.copy(mSCF.mo_coeff) eci = mCI.kernel(mo)[0] print_energy('CASSCF', eci) inp.timer.end('casscf') inp.timer.start('nevpt2') mpt2 = mrpt.NEVPT(mCI) ept2 = mpt2.kernel() + eci print_energy('NEVPT2', ept2) inp.timer.end('nevpt2') else: print ('ERROR: Unrecognized SCF method!') raise SystemExit # dump fcidump file if needed if inp.fcidump: if inp.filename[-4:].lower() == '.inp': fcifile = inp.filename[:-4] + '.fcidump' else: fcifile = inp.filename + '.fcidump' fcidump(mSCF, filename=fcifile, tol=1e-6) # plot MOs if needed if inp.mo2cube: from .mo_2_cube import save_MOs save_MOs(inp, mSCF, mSCF.mo_coeff) # save molden file if needed if inp.molden: from pyscf.tools import molden molden_file = inp.filename[:-4] + '.molden' molden.from_mo(inp.mol, molden_file, mSCF.mo_coeff, ene=mSCF.mo_energy) # save and return inp.mf = mSCF return inp
def convert_to_uhf(mf, out=None): '''Convert the given mean-field object to the corresponding unrestricted HF/KS object ''' from pyscf import scf from pyscf import dft def update_mo_(mf, mf1): _keys = mf._keys.union(mf1._keys) mf1.__dict__.update(mf.__dict__) mf1._keys = _keys if mf.mo_energy is not None: mf1.mo_energy = numpy.array((mf.mo_energy, mf.mo_energy)) mf1.mo_coeff = numpy.array((mf.mo_coeff, mf.mo_coeff)) mf1.mo_occ = numpy.array((mf.mo_occ > 0, mf.mo_occ == 2), dtype=numpy.double) return mf1 if out is not None: assert (isinstance(out, scf.uhf.UHF)) if isinstance(mf, scf.uhf.UHF): out.__dict.__update(mf) else: # RHF out = update_mo_(mf, out) return out else: hf_class = { scf.hf.RHF: scf.uhf.UHF, scf.rohf.ROHF: scf.uhf.UHF, scf.hf_symm.RHF: scf.uhf_symm.UHF, scf.hf_symm.ROHF: scf.uhf_symm.UHF } dft_class = { dft.rks.RKS: dft.uks.UKS, dft.roks.ROKS: dft.uks.UKS, dft.rks_symm.RKS: dft.uks_symm.UKS, dft.rks_symm.ROKS: dft.uks_symm.UKS } if isinstance(mf, scf.uhf.UHF): out = copy.copy(mf) elif mf.__class__ in hf_class: out = update_mo_(mf, scf.UHF(mf.mol)) elif mf.__class__ in dft_class: out = update_mo_(mf, dft.UKS(mf.mol)) else: msg = ('Warn: Converting a decorated RHF object to the decorated ' 'UHF object is unsafe.\nIt is recommended to create a ' 'decorated UHF object explicitly and pass it to ' 'convert_to_uhf function eg:\n' ' convert_to_uhf(mf, out=density_fit(scf.UHF(mol)))\n') sys.stderr.write(msg) # Python resolve the subclass inheritance dynamically based on MRO. We can # change the subclass inheritance order to substitute RHF/RKS with UHF/UKS. mro = mf.__class__.__mro__ mronew = None for i, cls in enumerate(mro): if cls in hf_class: mronew = mro[:i] + hf_class[cls].__mro__ break elif cls in dft_class: mronew = mro[:i] + dft_class[cls].__mro__ break if mronew is None: raise RuntimeError('%s object is not SCF object') out = update_mo_(mf, lib.overwrite_mro(mf, mronew)) return out
solve_mo1 = uks_nmr.solve_mo1 if __name__ == '__main__': from pyscf import gto from pyscf import dft mol = gto.Mole() mol.verbose = 0 mol.output = None mol.atom = [ ['Ne' , (0. , 0. , 0.)], ] mol.basis='631g' mol.build() mf = dft.UKS(mol).run() mag = Magnetizability(mf).kernel() print(lib.finger(mag) - -0.30375149255154221) mf.set(xc = 'b3lyp').run() mag = Magnetizability(mf).kernel() print(lib.finger(mag) - -0.3022331813238171) mol.atom = [ [1 , (0. , 0. , .917)], ['F' , (0. , 0. , 0. )], ] mol.basis = '6-31g' mol.build() mf = dft.UKS(mol).set(xc='lda,vwn').run() mag = Magnetizability(mf).kernel()
def kernel(self, mo1=None): assert(uhf_ssc.ZZ_ONLY) return uhf_ssc.SpinSpinCoupling.kernel(self, mo1) SSC = SpinSpinCoupling if __name__ == '__main__': from pyscf import lib, gto, dft mol = gto.M(atom=''' O 0 0 0 H 0 -0.757 0.587 H 0 0.757 0.587''', basis='6-31g') mf1 = dft.UKS(mol).set(xc='b3lyp').run() ssc = SSC(mf1) ssc.with_fc = True ssc.with_fcsd = True jj = ssc.kernel() from pyscf.prop.ssc import rks mol = gto.M(atom=''' O 0 0 0 H 0 -0.757 0.587 H 0 0.757 0.587''', basis='6-31g') mf = dft.RKS(mol).set(xc='b3lyp').run() ssc = rks.SSC(mf) ssc.with_fc = True
def calculate_flosic(ase_atoms=None, fname=None, spin=None, charge=0, debug=False, xc='LDA,PW', basis='6-311++Gss', ghost=False, verbose=0, max_cycle=300, conv_tol=1e-5, grid=3): # Initiliaze the calculation. # Choose a datatype. dt = [np.complex128, np.float64][1] # Get the geometry configuration. if ase_atoms == None: if fname is not None: try: ase_atoms = read(fname + '.xyz') except: return None, None else: print('No input found. Ending the calculation.') return None, None else: if fname == None: fname = 'Unknown_System' # xyz_to_nuclei_fod gives both an array for the init of pyscf # as well as an array containing all the fods and core positions. # Core and fods are given back as ase atoms objects. pyscf_atoms, nuclei, fod1, fod2, included = xyz_to_nuclei_fod(ase_atoms) # Get the spin configuration. if spin is None: spin = get_multiplicity(fname) # Set the basis. b = basis # Optional symmetry parameter. In this case: linear molecules. issymmetric = False if issymmetric: mol.symmetry = 'D2h' # Initiliaze the mol object. if ghost == True: mol = gto.M(atom=pyscf_atoms, basis={ 'default': b, 'GHOST1': gto.basis.load('sto3g', 'H'), 'GHOST2': gto.basis.load('sto3g', 'H') }, spin=spin, symmetry=issymmetric, charge=charge) elif ghost == False: mol = gto.M(atom=ase2pyscf(nuclei), basis={'default': b}, spin=spin, symmetry=issymmetric, charge=charge) if debug == True: print('Molecular Geometry: ', mol.atom) print('Spin Configuration: ', spin) # Initiliaze the DFT calculator. mf = dft.UKS(mol) mf.verbose = verbose mf.max_cycle = max_cycle mf.conv_tol = conv_tol if debug == True: mf.verbose = 4 # Grid level, default is 3. mf.grids.level = grid mf.xc = xc # Choose an xc functional. print('DFT calculator initilization: DONE.') print('Functional used:', mf.xc) # Do the calculation. # This is a one shot calculation. print('FLOSIC calculation entered in the one-shot mode.') # Ground state calculation. mf.kernel() print('Ground state calculation: DONE.') # Call the flosic routine. flosic_values = flosic( mol, mf, fod1, fod2, fname, datatype=dt, debug=debug, nuclei=nuclei, ) print('FLOSIC: DONE.') # FLO-SIC is done, output the values. return flosic_values
def test_nr_symm_ub3lypg(self): method = dft.UKS(h2osym) method.grids.prune = dft.gen_grid.treutler_prune method.grids.atom_grid = {"H": (50, 194), "O": (50, 194),} method.xc = 'b3lypg' self.assertAlmostEqual(method.scf(), -76.384928891413438, 9)
# Other common choices would be: # 'sto3g' - Minimal basis set. # 'cc-pvqz' - High accuracy basis set. b = '6-311++Gss' # With this information, we can build a mole object. # Mole objects hold the molecular geometry and further information on the molecule. # They are the input for DFT calculations. mol = gto.M(atom=molecule, basis={'default': b}, spin=spin_pol, charge=charge) # With this mole object, we can initiliaze the DFT calculation. # NOTE: This does not start the DFT calculation. dft_object = dft.UKS(mol) # Now we can customize the DFT calculation. dft_object.verbose = 4 # Amount of output. 4: full output. dft_object.max_cycle = 300 # Number of SCF iterations. dft_object.conv_tol = 1e-7 # Accuracy of the SCF cycle. dft_object.grids.level = 3 # Level of the numerical grid. 3 is the standard value. dft_object.xc = 'LDA,PW' # Exchange-correlation functional in the form: (exchange,correlation) # NOTE: As there exists only one way to express the exchange for LDA, there is only one identifier. # For LDA correlation there exist several. # Start the DFT calculation with kernel(). # Return value is the total energy. total_energy = dft_object.kernel()
def test_nr_symm_uks_lsda(self): method = dft.UKS(h2osym_cation) method.grids.prune = dft.gen_grid.treutler_prune method.grids.atom_grid = {"H": (50, 194), "O": (50, 194),} self.assertAlmostEqual(method.scf(), -75.350995324984709, 9)
self.so_eff_charge) if not self._scf.converged: log.warn('Ground state SCF is not converged') return self HFC = HyperfineCoupling if __name__ == '__main__': from pyscf import gto, scf, dft mol = gto.M(atom='C 0 0 0; O 0 0 1.12', basis='ccpvdz', spin=1, charge=1, verbose=3) mf = dft.UKS(mol).run() hfc = HFC(mf) hfc.verbose = 4 hfc.so_eff_charge = False print(lib.finger(hfc.kernel()) - 255.92807696823797) mol = gto.M(atom='H 0 0 0; H 0 0 1.', basis='ccpvdz', spin=1, charge=-1, verbose=3) mf = scf.UKS(mol).run() hfc = HFC(mf) hfc.cphf = True print(lib.finger(hfc.kernel()) - -25.896662045941071)
def test_nr_symm_uks_b3lypg(self): method = dft.UKS(h2osym_cation) method.xc = 'b3lypg' method.grids.prune = dft.gen_grid.treutler_prune method.grids.atom_grid = {"H": (50, 194), "O": (50, 194),} self.assertAlmostEqual(method.scf(), -75.927304010489976, 9)
nmoa), Lpqb.reshape(naux, nmob, nmob))) else: logger.warn(self, 'Memory may not be enough!') raise NotImplementedError if __name__ == '__main__': from pyscf import gto, dft, scf mol = gto.Mole() mol.verbose = 4 mol.atom = 'O 0 0 0' mol.basis = 'aug-cc-pvdz' mol.spin = 2 mol.build() mf = dft.UKS(mol) mf.xc = 'pbe0' mf.kernel() nocca = (mol.nelectron + mol.spin) // 2 noccb = mol.nelectron - nocca nmo = len(mf.mo_energy[0]) nvira = nmo - nocca nvirb = nmo - noccb gw = UGWAC(mf) gw.frozen = 0 gw.linearized = False gw.ac = 'pade' gw.kernel(orbs=range(nocca - 3, nocca + 3)) print(gw.mo_energy)
b_aa, b_ab, b_bb = b nocc_a, nvir_a, nocc_b, nvir_b = a_ab.shape a_aa = a_aa.reshape((nocc_a * nvir_a, nocc_a * nvir_a)) a_ab = a_ab.reshape((nocc_a * nvir_a, nocc_b * nvir_b)) a_bb = a_bb.reshape((nocc_b * nvir_b, nocc_b * nvir_b)) b_aa = b_aa.reshape((nocc_a * nvir_a, nocc_a * nvir_a)) b_ab = b_ab.reshape((nocc_a * nvir_a, nocc_b * nvir_b)) b_bb = b_bb.reshape((nocc_b * nvir_b, nocc_b * nvir_b)) a = numpy.bmat([[a_aa, a_ab], [a_ab.T, a_bb]]) b = numpy.bmat([[b_aa, b_ab], [b_ab.T, b_bb]]) e = numpy.linalg.eig(numpy.bmat([[a, b], [-b.conj(), -a.conj()]]))[0] lowest_e = numpy.sort(e[e.real > 0].real)[:nroots] return lowest_e mol.spin = 2 mf = scf.UHF(mol).run() a, b = tddft.TDHF(mf).get_ab() print('Direct diagoanlization:', diagonalize(a, b)) print('Reference:', tddft.TDHF(mf).kernel(nstates=4)[0]) mf = dft.UKS(mol).run(xc='lda,vwn') a, b = tddft.TDDFT(mf).get_ab() print('Direct diagoanlization:', diagonalize(a, b)) print('Reference:', tddft.TDDFT(mf).kernel(nstates=4)[0]) mf = dft.UKS(mol).run(xc='b3lyp') a, b = tddft.TDDFT(mf).get_ab() print('Direct diagoanlization:', diagonalize(a, b)) print('Reference:', tddft.TDDFT(mf).kernel(nstates=4)[0])