def compute_hf_energy(mol): olp = mol.obasis.compute_overlap(mol.lf) kin = mol.obasis.compute_kinetic(mol.lf) na = mol.obasis.compute_nuclear_attraction(mol.coordinates, mol.pseudo_numbers, mol.lf) er = mol.obasis.compute_electron_repulsion(mol.lf) external = {'nn': compute_nucnuc(mol.coordinates, mol.pseudo_numbers)} if hasattr(mol, 'exp_beta'): # assuming unrestricted terms = [ UTwoIndexTerm(kin, 'kin'), UDirectTerm(er, 'hartree'), UExchangeTerm(er, 'x_hf'), UTwoIndexTerm(na, 'ne'), ] ham = UEffHam(terms, external) dm_alpha = mol.exp_alpha.to_dm() dm_beta = mol.exp_beta.to_dm() ham.reset(dm_alpha, dm_beta) else: # assuming restricted terms = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RExchangeTerm(er, 'x_hf'), RTwoIndexTerm(na, 'ne'), ] ham = REffHam(terms, external) dm_alpha = mol.exp_alpha.to_dm() ham.reset(dm_alpha) return ham.compute_energy()
def check_methyl_os_tpss(scf_solver): """Try to converge the SCF for the methyl radical molecule with the TPSS functional. Parameters ---------- scf_solver : one of the SCFSolver types in HORTON A configured SCF solver that must be tested. """ fn_fchk = context.get_fn('test/methyl_tpss_321g.fchk') mol = IOData.from_file(fn_fchk) grid = BeckeMolGrid(mol.coordinates, mol.numbers, mol.pseudo_numbers, 'fine', random_rotate=False) olp = mol.obasis.compute_overlap() kin = mol.obasis.compute_kinetic() na = mol.obasis.compute_nuclear_attraction(mol.coordinates, mol.pseudo_numbers) er = mol.obasis.compute_electron_repulsion() external = {'nn': compute_nucnuc(mol.coordinates, mol.pseudo_numbers)} terms = [ UTwoIndexTerm(kin, 'kin'), UDirectTerm(er, 'hartree'), UGridGroup(mol.obasis, grid, [ ULibXCMGGA('x_tpss'), ULibXCMGGA('c_tpss'), ]), UTwoIndexTerm(na, 'ne'), ] ham = UEffHam(terms, external) # compute the energy before converging dm_alpha = mol.orb_alpha.to_dm() dm_beta = mol.orb_beta.to_dm() ham.reset(dm_alpha, dm_beta) ham.compute_energy() assert abs(ham.cache['energy'] - -39.6216986265) < 1e-3 # The convergence should be reasonable, not perfect because of limited # precision in the molden file: assert convergence_error_eigen(ham, olp, mol.orb_alpha, mol.orb_beta) < 1e-3 # keep a copy of the orbital energies expected_alpha_energies = mol.orb_alpha.energies.copy() expected_beta_energies = mol.orb_beta.energies.copy() # Converge from scratch occ_model = AufbauOccModel(5, 4) check_solve(ham, scf_solver, occ_model, olp, kin, na, mol.orb_alpha, mol.orb_beta) # test orbital energies assert abs(mol.orb_alpha.energies - expected_alpha_energies).max() < 2e-3 assert abs(mol.orb_beta.energies - expected_beta_energies).max() < 2e-3 ham.compute_energy() # compare with assert abs(ham.cache['energy_kin'] - 38.98408965928) < 1e-2 assert abs(ham.cache['energy_ne'] - -109.2368837076) < 1e-2 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_libxc_mgga_x_tpss'] + ham.cache['energy_libxc_mgga_c_tpss'] - 21.55131145126) < 1e-2 assert abs(ham.cache['energy'] - -39.6216986265) < 1e-3 assert abs(ham.cache['energy_nn'] - 9.0797839705) < 1e-5
def check_h3_os_pbe(scf_solver): fn_fchk = context.get_fn("test/h3_pbe_321g.fchk") mol = IOData.from_file(fn_fchk) grid = BeckeMolGrid(mol.coordinates, mol.numbers, mol.pseudo_numbers, "veryfine", random_rotate=False) olp = mol.obasis.compute_overlap(mol.lf) kin = mol.obasis.compute_kinetic(mol.lf) na = mol.obasis.compute_nuclear_attraction(mol.coordinates, mol.pseudo_numbers, mol.lf) er = mol.obasis.compute_electron_repulsion(mol.lf) external = {"nn": compute_nucnuc(mol.coordinates, mol.pseudo_numbers)} terms = [ UTwoIndexTerm(kin, "kin"), UDirectTerm(er, "hartree"), UGridGroup(mol.obasis, grid, [ULibXCGGA("x_pbe"), ULibXCGGA("c_pbe")]), UTwoIndexTerm(na, "ne"), ] ham = UEffHam(terms, external) # compute the energy before converging dm_alpha = mol.exp_alpha.to_dm() dm_beta = mol.exp_beta.to_dm() ham.reset(dm_alpha, dm_beta) ham.compute_energy() assert abs(ham.cache["energy"] - -1.593208400939354e00) < 1e-5 # The convergence should be reasonable, not perfect because of limited # precision in Gaussian fchk file: assert convergence_error_eigen(ham, mol.lf, olp, mol.exp_alpha, mol.exp_beta) < 2e-6 # Converge from scratch occ_model = AufbauOccModel(2, 1) check_solve(ham, scf_solver, occ_model, mol.lf, olp, kin, na, mol.exp_alpha, mol.exp_beta) # test orbital energies expected_energies = np.array( [-5.41141676e-01, -1.56826691e-01, 2.13089637e-01, 7.13565167e-01, 7.86810564e-01, 1.40663544e00] ) assert abs(mol.exp_alpha.energies - expected_energies).max() < 2e-5 expected_energies = np.array( [-4.96730336e-01, -5.81411249e-02, 2.73586652e-01, 7.41987185e-01, 8.76161160e-01, 1.47488421e00] ) assert abs(mol.exp_beta.energies - expected_energies).max() < 2e-5 ham.compute_energy() # compare with g09 assert abs(ham.cache["energy_ne"] - -6.934705182067e00) < 1e-5 assert abs(ham.cache["energy_kin"] - 1.948808793424e00) < 1e-5 assert ( abs( ham.cache["energy_hartree"] + ham.cache["energy_libxc_gga_x_pbe"] + ham.cache["energy_libxc_gga_c_pbe"] - 1.502769385597e00 ) < 1e-5 ) assert abs(ham.cache["energy"] - -1.593208400939354e00) < 1e-5 assert abs(ham.cache["energy_nn"] - 1.8899186021) < 1e-8
def check_h3_os_pbe(scf_solver): fn_fchk = context.get_fn('test/h3_pbe_321g.fchk') mol = IOData.from_file(fn_fchk) grid = BeckeMolGrid(mol.coordinates, mol.numbers, mol.pseudo_numbers, 'veryfine', random_rotate=False) olp = mol.obasis.compute_overlap() kin = mol.obasis.compute_kinetic() na = mol.obasis.compute_nuclear_attraction(mol.coordinates, mol.pseudo_numbers) er = mol.obasis.compute_electron_repulsion() external = {'nn': compute_nucnuc(mol.coordinates, mol.pseudo_numbers)} terms = [ UTwoIndexTerm(kin, 'kin'), UDirectTerm(er, 'hartree'), UGridGroup(mol.obasis, grid, [ ULibXCGGA('x_pbe'), ULibXCGGA('c_pbe'), ]), UTwoIndexTerm(na, 'ne'), ] ham = UEffHam(terms, external) # compute the energy before converging dm_alpha = mol.orb_alpha.to_dm() dm_beta = mol.orb_beta.to_dm() ham.reset(dm_alpha, dm_beta) ham.compute_energy() assert abs(ham.cache['energy'] - -1.593208400939354E+00) < 1e-5 # The convergence should be reasonable, not perfect because of limited # precision in Gaussian fchk file: assert convergence_error_eigen(ham, olp, mol.orb_alpha, mol.orb_beta) < 2e-6 # Converge from scratch occ_model = AufbauOccModel(2, 1) check_solve(ham, scf_solver, occ_model, olp, kin, na, mol.orb_alpha, mol.orb_beta) # test orbital energies expected_energies = np.array([ -5.41141676E-01, -1.56826691E-01, 2.13089637E-01, 7.13565167E-01, 7.86810564E-01, 1.40663544E+00 ]) assert abs(mol.orb_alpha.energies - expected_energies).max() < 2e-5 expected_energies = np.array([ -4.96730336E-01, -5.81411249E-02, 2.73586652E-01, 7.41987185E-01, 8.76161160E-01, 1.47488421E+00 ]) assert abs(mol.orb_beta.energies - expected_energies).max() < 2e-5 ham.compute_energy() # compare with g09 assert abs(ham.cache['energy_ne'] - -6.934705182067E+00) < 1e-5 assert abs(ham.cache['energy_kin'] - 1.948808793424E+00) < 1e-5 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_libxc_gga_x_pbe'] + ham.cache['energy_libxc_gga_c_pbe'] - 1.502769385597E+00) < 1e-5 assert abs(ham.cache['energy'] - -1.593208400939354E+00) < 1e-5 assert abs(ham.cache['energy_nn'] - 1.8899186021) < 1e-8