def add_esp(fchkfile, hdf5file): npa_charges = IOData.from_file(fchkfile).npa_charges esp_charges = IOData.from_file(fchkfile).esp_charges mul_charges = IOData.from_file(fchkfile).mulliken_charges g = h5py.File('pop_results.hdf5', 'a') if 'npa' in g.keys(): del g['npa'] g.create_dataset('/npa', data=npa_charges) if 'esp' in g.keys(): del g['esp'] g.create_dataset('/esp', data=esp_charges) if 'mulliken' in g.keys(): del g['mulliken'] g.create_dataset('/mulliken', data=esp_charges)
def check_hf_cs_hf(scf_solver): fn_fchk = context.get_fn('test/hf_sto3g.fchk') mol = IOData.from_file(fn_fchk) 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 = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RExchangeTerm(er, 'x_hf'), RTwoIndexTerm(na, 'ne'), ] ham = REffHam(terms, external) occ_model = AufbauOccModel(5) check_solve(ham, scf_solver, occ_model, mol.lf, olp, kin, na, mol.exp_alpha) # test orbital energies expected_energies = np.array([ -2.59083334E+01, -1.44689996E+00, -5.57467136E-01, -4.62288194E-01, -4.62288194E-01, 5.39578910E-01, ]) assert abs(mol.exp_alpha.energies - expected_energies).max() < 1e-5 ham.compute_energy() # compare with g09 assert abs(ham.cache['energy'] - -9.856961609951867E+01) < 1e-8 assert abs(ham.cache['energy_kin'] - 9.766140786239E+01) < 2e-7 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_x_hf'] - 4.561984106482E+01) < 1e-6 assert abs(ham.cache['energy_ne'] - -2.465756615329E+02) < 1e-6 assert abs(ham.cache['energy_nn'] - 4.7247965053) < 1e-8
def check_hf_cs_hf(scf_solver): fn_fchk = context.get_fn('test/hf_sto3g.fchk') mol = IOData.from_file(fn_fchk) 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 = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RExchangeTerm(er, 'x_hf'), RTwoIndexTerm(na, 'ne'), ] ham = REffHam(terms, external) occ_model = AufbauOccModel(5) check_solve(ham, scf_solver, occ_model, olp, kin, na, mol.orb_alpha) # test orbital energies expected_energies = np.array([ -2.59083334E+01, -1.44689996E+00, -5.57467136E-01, -4.62288194E-01, -4.62288194E-01, 5.39578910E-01, ]) assert abs(mol.orb_alpha.energies - expected_energies).max() < 1e-5 ham.compute_energy() # compare with g09 assert abs(ham.cache['energy'] - -9.856961609951867E+01) < 1e-8 assert abs(ham.cache['energy_kin'] - 9.766140786239E+01) < 2e-7 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_x_hf'] - 4.561984106482E+01) < 1e-6 assert abs(ham.cache['energy_ne'] - -2.465756615329E+02) < 1e-6 assert abs(ham.cache['energy_nn'] - 4.7247965053) < 1e-8
def test_two_integrals(): """ Test function to compute modified two-electron integrals. """ function = compute_two_integrals mol = IOData(numbers=np.array([1]), coordinates=np.array([[0., 0., 0]])) obasis = [0, 1, 2] approxs = [2] pars = [3] # Check obasis assert_raises(TypeError, function, obasis, approxs, pars) obasis = get_gobasis(mol.coordinates, mol.numbers, '3-21G') # Check approxs assert_raises(TypeError, function, obasis, approxs, pars) approxs = ['erf'] # Check pars assert_raises(TypeError, function, obasis, approxs, pars) pars = [[0.1]] approxs = ['nada'] # Check approxs options assert_raises(ValueError, function, obasis, approxs, pars) approxs = ['erf'] # Check the actual function erf_ref = obasis.compute_erf_repulsion(0.1) erf = function(obasis, approxs, pars) assert (erf == erf_ref).all() gauss = obasis.compute_gauss_repulsion(1.0, 1.5) erfgau_ref = erf + gauss erfgau = function(obasis, ['erf', 'gauss'], [[0.1], [1.0, 1.5]]) assert (erfgau == erfgau_ref).all()
def setUp(self): super(Horton2Test, self).setUp() self.data, self.logfile = getdatafile("Gaussian", "basicGaussian16", ["dvb_un_sp.fchk"]) datadir = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", "..", "data")) inputfile = os.path.join(datadir, "Gaussian", "basicGaussian16", "dvb_un_sp.fchk") self._old_horton = False self._found_horton = find_package("horton") if self._found_horton: try: from horton import __version__ except: self._old_horton = ( True # Old horton versions do not have this __version__ attribute ) else: if __version__[0] == "2": from horton.io.iodata import IOData from horton import log log.set_level( 0 ) # This suppresses horton outputs so that they do not flood the test log. self._hortonver = 2 self.iodat = IOData.from_file(inputfile)
def from_files(cls, fns, agspec='fine'): ''' Construct a ProAtomDB from a series of HORTON checkpoint files. **Arguments:** fns_chk A list of atomic output files. **Optional arguments:** agspec A specifications of the atomic grid. This can either be an instance of the AtomicGridSpec object, or the first argument of its constructor. ''' if not isinstance(agspec, AtomicGridSpec): agspec = AtomicGridSpec(agspec) records = [] for fn in fns: # Load atomic data with timer.section('Load proatom'): mol = IOData.from_file(fn) with timer.section('Proatom grid'): records.append(ProAtomRecord.from_iodata(mol, agspec)) return cls(records)
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_lih_os_hf(scf_solver): fn_fchk = context.get_fn('test/li_h_3-21G_hf_g09.fchk') mol = IOData.from_file(fn_fchk) 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'), UExchangeTerm(er, 'x_hf'), UTwoIndexTerm(na, 'ne'), ] ham = UEffHam(terms, external) occ_model = AufbauOccModel(2, 1) check_solve(ham, scf_solver, occ_model, mol.lf, olp, kin, na, mol.exp_alpha, mol.exp_beta) expected_alpha_energies = np.array([ -2.76116635E+00, -7.24564188E-01, -1.79148636E-01, -1.28235698E-01, -1.28235698E-01, -7.59817520E-02, -1.13855167E-02, 6.52484445E-03, 6.52484445E-03, 7.52201895E-03, 9.70893294E-01, ]) expected_beta_energies = np.array([ -2.76031162E+00, -2.08814026E-01, -1.53071066E-01, -1.25264964E-01, -1.25264964E-01, -1.24605870E-02, 5.12761388E-03, 7.70499854E-03, 7.70499854E-03, 2.85176080E-02, 1.13197479E+00, ]) assert abs(mol.exp_alpha.energies - expected_alpha_energies).max() < 1e-5 assert abs(mol.exp_beta.energies - expected_beta_energies).max() < 1e-5 ham.compute_energy() # compare with g09 assert abs(ham.cache['energy'] - -7.687331212191962E+00) < 1e-8 assert abs(ham.cache['energy_kin'] - 7.640603924034E+00) < 2e-7 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_x_hf'] - 2.114420907894E+00) < 1e-7 assert abs(ham.cache['energy_ne'] - -1.811548789281E+01) < 2e-7 assert abs(ham.cache['energy_nn'] - 0.6731318487) < 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(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_water_cs_m05(scf_solver): """Try to converge the SCF for the water molecule with the M05 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/water_m05_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)} libxc_term = RLibXCHybridMGGA('xc_m05') terms = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RGridGroup(mol.obasis, grid, [libxc_term]), RExchangeTerm(er, 'x_hf', libxc_term.get_exx_fraction()), RTwoIndexTerm(na, 'ne'), ] ham = REffHam(terms, external) # compute the energy before converging dm_alpha = mol.orb_alpha.to_dm() ham.reset(dm_alpha) ham.compute_energy() assert abs(ham.cache['energy'] - -75.9532086800) < 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) < 1e-3 # keep a copy of the orbital energies expected_alpha_energies = mol.orb_alpha.energies.copy() # Converge from scratch occ_model = AufbauOccModel(5) check_solve(ham, scf_solver, occ_model, olp, kin, na, mol.orb_alpha) # test orbital energies assert abs(mol.orb_alpha.energies - expected_alpha_energies).max() < 2e-3 ham.compute_energy() # compare with assert abs(ham.cache['energy_kin'] - 75.54463056278) < 1e-2 assert abs(ham.cache['energy_ne'] - -198.3003887880) < 1e-2 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_x_hf'] + ham.cache['energy_libxc_hyb_mgga_xc_m05'] - 3.764537450376E+01) < 1e-2 assert abs(ham.cache['energy'] - -75.9532086800) < 1e-3 assert abs(ham.cache['energy_nn'] - 9.1571750414) < 1e-5
def check_water_cs_hfs(scf_solver): fn_fchk = context.get_fn('test/water_hfs_321g.fchk') mol = IOData.from_file(fn_fchk) grid = BeckeMolGrid(mol.coordinates, mol.numbers, mol.pseudo_numbers, 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 = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RGridGroup(mol.obasis, grid, [ RDiracExchange(), ]), RTwoIndexTerm(na, 'ne'), ] ham = REffHam(terms, external) # The convergence should be reasonable, not perfect because of limited # precision in Gaussian fchk file and different integration grids: assert convergence_error_eigen(ham, olp, mol.orb_alpha) < 3e-5 # Recompute the orbitals and orbital energies. This should be reasonably OK. dm_alpha = mol.orb_alpha.to_dm() ham.reset(dm_alpha) ham.compute_energy() fock_alpha = np.zeros(dm_alpha.shape) ham.compute_fock(fock_alpha) mol.orb_alpha.from_fock(fock_alpha, olp) expected_energies = np.array([ -1.83691041E+01, -8.29412411E-01, -4.04495188E-01, -1.91740814E-01, -1.32190590E-01, 1.16030419E-01, 2.08119657E-01, 9.69825207E-01, 9.99248500E-01, 1.41697384E+00, 1.47918828E+00, 1.61926596E+00, 2.71995350E+00 ]) assert abs(mol.orb_alpha.energies - expected_energies).max() < 2e-4 assert abs(ham.cache['energy_ne'] - -1.977921986200E+02) < 1e-7 assert abs(ham.cache['energy_kin'] - 7.525067610865E+01) < 1e-9 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_x_dirac'] - 3.864299848058E+01) < 2e-4 assert abs(ham.cache['energy'] - -7.474134898935590E+01) < 2e-4 assert abs(ham.cache['energy_nn'] - 9.1571750414) < 2e-8 # Converge from scratch and check energies occ_model = AufbauOccModel(5) check_solve(ham, scf_solver, occ_model, olp, kin, na, mol.orb_alpha) ham.compute_energy() assert abs(ham.cache['energy_ne'] - -1.977921986200E+02) < 1e-4 assert abs(ham.cache['energy_kin'] - 7.525067610865E+01) < 1e-4 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_x_dirac'] - 3.864299848058E+01) < 2e-4 assert abs(ham.cache['energy'] - -7.474134898935590E+01) < 2e-4
def check_water_cs_hfs(scf_solver): fn_fchk = context.get_fn('test/water_hfs_321g.fchk') mol = IOData.from_file(fn_fchk) grid = BeckeMolGrid(mol.coordinates, mol.numbers, mol.pseudo_numbers, 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 = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RGridGroup(mol.obasis, grid, [ RDiracExchange(), ]), RTwoIndexTerm(na, 'ne'), ] ham = REffHam(terms, external) # The convergence should be reasonable, not perfect because of limited # precision in Gaussian fchk file and different integration grids: assert convergence_error_eigen(ham, mol.lf, olp, mol.exp_alpha) < 3e-5 # Recompute the orbitals and orbital energies. This should be reasonably OK. dm_alpha = mol.exp_alpha.to_dm() ham.reset(dm_alpha) ham.compute_energy() fock_alpha = mol.lf.create_two_index() ham.compute_fock(fock_alpha) mol.exp_alpha.from_fock(fock_alpha, olp) expected_energies = np.array([ -1.83691041E+01, -8.29412411E-01, -4.04495188E-01, -1.91740814E-01, -1.32190590E-01, 1.16030419E-01, 2.08119657E-01, 9.69825207E-01, 9.99248500E-01, 1.41697384E+00, 1.47918828E+00, 1.61926596E+00, 2.71995350E+00 ]) assert abs(mol.exp_alpha.energies - expected_energies).max() < 2e-4 assert abs(ham.cache['energy_ne'] - -1.977921986200E+02) < 1e-7 assert abs(ham.cache['energy_kin'] - 7.525067610865E+01) < 1e-9 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_x_dirac'] - 3.864299848058E+01) < 2e-4 assert abs(ham.cache['energy'] - -7.474134898935590E+01) < 2e-4 assert abs(ham.cache['energy_nn'] - 9.1571750414) < 2e-8 # Converge from scratch and check energies occ_model = AufbauOccModel(5) check_solve(ham, scf_solver, occ_model, mol.lf, olp, kin, na, mol.exp_alpha) ham.compute_energy() assert abs(ham.cache['energy_ne'] - -1.977921986200E+02) < 1e-4 assert abs(ham.cache['energy_kin'] - 7.525067610865E+01) < 1e-4 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_x_dirac'] - 3.864299848058E+01) < 2e-4 assert abs(ham.cache['energy'] - -7.474134898935590E+01) < 2e-4
def check_lih_os_hf(scf_solver): fn_fchk = context.get_fn("test/li_h_3-21G_hf_g09.fchk") mol = IOData.from_file(fn_fchk) 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"), UExchangeTerm(er, "x_hf"), UTwoIndexTerm(na, "ne")] ham = UEffHam(terms, external) occ_model = AufbauOccModel(2, 1) check_solve(ham, scf_solver, occ_model, mol.lf, olp, kin, na, mol.exp_alpha, mol.exp_beta) expected_alpha_energies = np.array( [ -2.76116635e00, -7.24564188e-01, -1.79148636e-01, -1.28235698e-01, -1.28235698e-01, -7.59817520e-02, -1.13855167e-02, 6.52484445e-03, 6.52484445e-03, 7.52201895e-03, 9.70893294e-01, ] ) expected_beta_energies = np.array( [ -2.76031162e00, -2.08814026e-01, -1.53071066e-01, -1.25264964e-01, -1.25264964e-01, -1.24605870e-02, 5.12761388e-03, 7.70499854e-03, 7.70499854e-03, 2.85176080e-02, 1.13197479e00, ] ) assert abs(mol.exp_alpha.energies - expected_alpha_energies).max() < 1e-5 assert abs(mol.exp_beta.energies - expected_beta_energies).max() < 1e-5 ham.compute_energy() # compare with g09 assert abs(ham.cache["energy"] - -7.687331212191962e00) < 1e-8 assert abs(ham.cache["energy_kin"] - 7.640603924034e00) < 2e-7 assert abs(ham.cache["energy_hartree"] + ham.cache["energy_x_hf"] - 2.114420907894e00) < 1e-7 assert abs(ham.cache["energy_ne"] - -1.811548789281e01) < 2e-7 assert abs(ham.cache["energy_nn"] - 0.6731318487) < 1e-8
def check_co_cs_pbe(scf_solver): fn_fchk = context.get_fn('test/co_pbe_sto3g.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(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 = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RGridGroup(mol.obasis, grid, [ RLibXCGGA('x_pbe'), RLibXCGGA('c_pbe'), ]), RTwoIndexTerm(na, 'ne'), ] ham = REffHam(terms, external) # Test energy before scf energy, focks = helper_compute(ham, mol.lf, mol.exp_alpha) assert abs(energy - -1.116465967841901E+02) < 1e-4 # 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) < 1e-5 # Converge from scratch occ_model = AufbauOccModel(7) check_solve(ham, scf_solver, occ_model, mol.lf, olp, kin, na, mol.exp_alpha) # test orbital energies expected_energies = np.array([ -1.86831122E+01, -9.73586915E+00, -1.03946082E+00, -4.09331776E-01, -3.48686522E-01, -3.48686522E-01, -2.06049056E-01, 5.23730418E-02, 5.23730418E-02, 6.61093726E-01 ]) assert abs(mol.exp_alpha.energies - expected_energies).max() < 1e-2 ham.compute_energy() # compare with g09 assert abs(ham.cache['energy_ne'] - -3.072370116827E+02) < 1e-2 assert abs(ham.cache['energy_kin'] - 1.103410779827E+02) < 1e-2 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_libxc_gga_x_pbe'] + ham.cache['energy_libxc_gga_c_pbe'] - 6.273115782683E+01) < 1e-2 assert abs(ham.cache['energy'] - -1.116465967841901E+02) < 1e-4 assert abs(ham.cache['energy_nn'] - 22.5181790889) < 1e-7
def write_random_lta_cube(dn, fn_cube): '''Write a randomized cube file''' # start from an existing cube file mol = IOData.from_file(context.get_fn('test/lta_gulp.cif')) # Define a uniform grid with only 1000 points, to make the tests fast. ugrid = UniformGrid(np.zeros(3, float), mol.cell.rvecs*0.1, np.array([10, 10, 10]), np.array([1, 1, 1])) # Write to the file dn/fn_cube mol.cube_data = np.random.uniform(0, 1, ugrid.shape) mol.grid = ugrid mol.to_file(os.path.join(dn, fn_cube)) return mol
def load_atom(self, dn_mult, ext): fn = '%s/atom.%s' % (dn_mult, ext) if not os.path.isfile(fn): return None, None try: mol = IOData.from_file(fn) except: return None, None mol.energy = self._get_energy(mol, dn_mult) return mol, mol.energy
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
def write_random_lta_cube(dn, fn_cube): '''Write a randomized cube file''' # start from an existing cube file mol = IOData.from_file(context.get_fn('test/lta_gulp.cif')) # Define a uniform grid with only 1000 points, to make the tests fast. ugrid = UniformGrid(np.zeros(3, float), mol.cell.rvecs * 0.1, np.array([10, 10, 10]), np.array([1, 1, 1])) # Write to the file dn/fn_cube mol.cube_data = np.random.uniform(0, 1, ugrid.shape) mol.grid = ugrid mol.to_file(os.path.join(dn, fn_cube)) return mol
def load_rho(coordinates, numbers, fn_cube, ref_ugrid, stride, chop): '''Load densities from a file, reduce by stride, chop and check ugrid **Arguments:** coordinates An array with shape (N, 3) containing atomic coordinates. numbers A vector with shape (N,) containing atomic numbers. fn_cube The cube file with the electron density. ref_ugrid A reference ugrid that must match the one from the density cube file (after reduction). stride The reduction factor. chop The number of slices to chop of the grid in each direction. ''' if fn_cube is None: # Load the built-in database of proatoms natom = len(numbers) numbers = np.unique(numbers) proatomdb = ProAtomDB.from_refatoms(numbers, max_cation=0, max_anion=0, agspec='fine') # Construct the pro-density rho = np.zeros(ref_ugrid.shape) for i in xrange(natom): spline = proatomdb.get_spline(numbers[i]) ref_ugrid.eval_spline(spline, coordinates[i], rho) else: # Load cube mol_rho = IOData.from_file(fn_cube) rho = mol_rho.cube_data ugrid = mol_rho.grid # Reduce grid size if stride > 1: rho, ugrid = reduce_data(rho, ugrid, stride, chop) # Compare with ref_ugrid (only shape) if (ugrid.shape != ref_ugrid.shape).any(): raise ValueError('The densities file does not contain the same amount if information as the potential file.') return rho
def test_integrals_wrapper_init(): """ Test the integral wrapper. """ function = IntegralsWrapper mol = [1, 2] obasis = [2, 3, 1, 3] one_approx = [0, 1] two_approx = [0] pars = [0, 3] orbs = 'orbs' # Check mol assert_raises(TypeError, function, mol, obasis, one_approx, two_approx, pars, orbs) mol = IOData(numbers=np.array([1]), coordinates=np.array([[0., 0., 0]])) # Check obasis assert_raises(TypeError, function, mol, obasis, one_approx, two_approx, pars, orbs) obasis = get_gobasis(mol.coordinates, mol.numbers, '3-21G') # Check one_approx assert_raises(TypeError, function, mol, obasis, one_approx, two_approx, pars, orbs) one_approx = ['man'] # Check options for one_approx assert_raises(ValueError, function, mol, obasis, one_approx, two_approx, pars, orbs) one_approx = ['standard'] del function function = IntegralsWrapper # Check two_approx assert_raises(TypeError, function, mol, obasis, one_approx, two_approx, pars, orbs) two_approx = ['nada'] # Check for options two_approx assert_raises(ValueError, function, mol, obasis, one_approx, two_approx, pars, orbs) two_approx = ['erf', 'gauss'] # Check for pars assert_raises(TypeError, function, mol, obasis, one_approx, two_approx, pars, orbs) pars = [[0.1], [1.0, 1.5]] # Check for orbs assert_raises(TypeError, function, mol, obasis, one_approx, two_approx, pars, orbs) orbs = [Orbitals(obasis.nbasis)]
def test_standard_one(): """ Test the standard one-electron integrals. """ function = compute_standard_one_integrals mol = [1, 2] obasis = [2, 3, 1, 3] # Check mol assert_raises(TypeError, function, mol, obasis) mol = IOData(numbers=np.array([1]), coordinates=np.array([[0., 0., 0]])) # Check obasis assert_raises(TypeError, function, mol, obasis) obasis = get_gobasis(mol.coordinates, mol.numbers, '3-21G') # Check the actual function kin = obasis.compute_kinetic() na = obasis.compute_nuclear_attraction(mol.coordinates, mol.pseudo_numbers) one_ref = kin + na one = function(mol, obasis) assert (one == one_ref).all()
def test_erfgau_truc(): """ Test the CI energy of the long-range Hamiltonian, using the error function """ mol = IOData(numbers=np.array([2]), coordinates=np.array([[0., 0., 0.]])) obasis = get_gobasis(mol.coordinates, mol.numbers, 'aug-cc-pvdz') one_approx = ['standard'] two_approx = ['erfgau'] mu = 0.01 c = 229.94 a = 103.36 pars = [[mu, c, a]] kin, natt, olp, er = prepare_integrals(mol, obasis) na = 1 nb = 1 er_ref = obasis.compute_electron_repulsion() hf_energy, core_energy, orbs = compute_hf(mol, obasis, na, nb, kin, natt, er, olp) modintegrals = IntegralsWrapper(mol, obasis, one_approx, two_approx, pars, orbs) # Transform integrals to MO basis (one_mo_ref, ), (two_mo_ref, ) = transform_integrals( kin + natt, er_ref, 'tensordot', orbs[0]) refintegrals = [one_mo_ref, two_mo_ref] optimizer = FullErfGauOptimizer(obasis.nbasis, core_energy, modintegrals, refintegrals, na, nb, mu=mu) optimizer.set_olp(olp) optimizer.set_orb_alpha(orbs[0]) optimizer.set_dm_alpha(orbs[0].to_dm()) optimizer.optype = 'standard' cpars = [c, a] optimizer.naturals = True energy = optimizer.compute_energy(cpars) print "energy", energy print "mu energy", optimizer.mu_energy
def test_hf_orbitals(): """ Check if HF orbitals are orthormal """ mol = IOData(numbers=np.array([2]), coordinates=np.array([[0., 0., 0.]])) obasis = get_gobasis(mol.coordinates, mol.numbers, 'aug-cc-pvdz') kin, natt, olp, er = prepare_integrals(mol, obasis) er_ref = obasis.compute_electron_repulsion() hf_energy, core_energy, orbs = compute_hf(mol, obasis, na, nb, kin, natt, er, olp) # Define a numerical integration grid needed for integration orblist = np.array(range(obasis.nbasis)) for i in orblist: for j in orblist: overlap = 0.0 for a in orblist: for b in orblist: overlap += orbs[0].coeffs[a, i] * orbs[0].coeffs[ b, j] * olp[a, b] if i == j: assert abs(overlap - 1.0) < 1e-5
def check_lih_os_hf(scf_solver): fn_fchk = context.get_fn('test/li_h_3-21G_hf_g09.fchk') mol = IOData.from_file(fn_fchk) 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'), UExchangeTerm(er, 'x_hf'), UTwoIndexTerm(na, 'ne'), ] ham = UEffHam(terms, external) occ_model = AufbauOccModel(2, 1) check_solve(ham, scf_solver, occ_model, olp, kin, na, mol.orb_alpha, mol.orb_beta) expected_alpha_energies = np.array([ -2.76116635E+00, -7.24564188E-01, -1.79148636E-01, -1.28235698E-01, -1.28235698E-01, -7.59817520E-02, -1.13855167E-02, 6.52484445E-03, 6.52484445E-03, 7.52201895E-03, 9.70893294E-01, ]) expected_beta_energies = np.array([ -2.76031162E+00, -2.08814026E-01, -1.53071066E-01, -1.25264964E-01, -1.25264964E-01, -1.24605870E-02, 5.12761388E-03, 7.70499854E-03, 7.70499854E-03, 2.85176080E-02, 1.13197479E+00, ]) assert abs(mol.orb_alpha.energies - expected_alpha_energies).max() < 1e-5 assert abs(mol.orb_beta.energies - expected_beta_energies).max() < 1e-5 ham.compute_energy() # compare with g09 assert abs(ham.cache['energy'] - -7.687331212191962E+00) < 1e-8 assert abs(ham.cache['energy_kin'] - 7.640603924034E+00) < 2e-7 assert abs(ham.cache['energy_hartree'] + ham.cache['energy_x_hf'] - 2.114420907894E+00) < 1e-7 assert abs(ham.cache['energy_ne'] - -1.811548789281E+01) < 2e-7 assert abs(ham.cache['energy_nn'] - 0.6731318487) < 1e-8
def test_two_integrals_wrapper_ncore(): """ Test function to compute modified two-electron wrapper with frozen core. """ function = IntegralsWrapper mol = IOData(numbers=np.array([4]), coordinates=np.array([[0., 0., 0]])) obasis = get_gobasis(mol.coordinates, mol.numbers, '3-21G') one_approx = ['standard'] two_approx = ['erf'] pars = [[0.1]] na = 2 nb = 2 kin, natt, olp, er = prepare_integrals(mol, obasis) hf_energy, core_energy, orbs = compute_hf(mol, obasis, na, nb, kin, natt, er, olp) ncore = 1.0 # Check ncore assert_raises(TypeError, function, mol, obasis, one_approx, two_approx, pars, orbs, ncore) ncore = 1 # Check core energy assert_raises(ValueError, function, mol, obasis, one_approx, two_approx, pars, orbs, ncore) del function # Check actual function result one_ref = kin + natt erf_ref = obasis.compute_erf_repulsion(0.1) nactive = obasis.nbasis - ncore ints = IntegralsWrapper(mol, obasis, one_approx, two_approx, pars, orbs, ncore, core_energy) one_mo, two_mo, core_energy = split_core_active(one_ref, erf_ref, core_energy, orbs[0], ncore=ncore, nactive=nactive) assert core_energy == ints.core_energy assert (ints.one == one_mo).all() assert (ints.two == two_mo).all()
def add_npa(fchkfile, hdf5file): npa_charges = IOData.from_file(fchkfile).npa_charges g = h5py.File('pop_results.hdf5', 'a') if 'npa' in g.keys(): del g['npa'] g.create_dataset('/npa', data=npa_charges)
def test_natural_orbitals(): """ Check if HF orbitals are orthormal """ mol = IOData(numbers=np.array([4]), coordinates=np.array([[0., 0., 0.]])) obasis = get_gobasis(mol.coordinates, mol.numbers, 'cc-pvdz') one_approx = ['standard'] two_approx = ['erfgau'] c = 1.9 * 0.9 a = (1.5 * 0.9)**2 pars = [[0.9, c, a]] kin, natt, olp, er = prepare_integrals(mol, obasis) na = 2 nb = 2 nelec = na + nb er_ref = obasis.compute_electron_repulsion() hf_energy, core_energy, orbs = compute_hf(mol, obasis, na, nb, kin, natt, er, olp) # Define a numerical integration grid needed for integration grid = BeckeMolGrid(mol.coordinates, mol.numbers, mol.pseudo_numbers) modintegrals = IntegralsWrapper(mol, obasis, one_approx, two_approx, pars, orbs) # Transform integrals to NO basis (one_mo, ), (two_mo, ) = transform_integrals(kin + natt, er_ref, 'tensordot', orbs[0]) refintegrals = [one_mo, two_mo] optimizer = FullErfGauOptimizer(obasis.nbasis, core_energy, modintegrals, refintegrals, na, nb, mu=0.9) optimizer.set_olp(olp) # Make occupations for determinants nbasis = obasis.nbasis civec0 = [] a0 = list('0' * nbasis) a0[0] = '1' a0[1] = '1' b0 = a0 a0 = a0[::-1] a0 = ''.join(a0) b0 = b0[::-1] b0 = ''.join(b0) vec = '0b%s%s' % (b0, a0) # Convert bitstring to integer vec = int(vec, 2) civec0.append(vec) civec1 = [] civec1.append(vec) a1 = list('0' * nbasis) a1[0] = '1' a1[2] = '1' b1 = a1 a1 = a1[::-1] a1 = ''.join(a1) b1 = b1[::-1] b1 = ''.join(b1) vec1 = '0b%s%s' % (b1, a1) vec1 = int(vec1, 2) civec1.append(vec1) cienergy0, cicoeffs0, civec = compute_ci_fanCI(nelec, nbasis, one_mo, two_mo, core_energy, civec0) (dm1_0, ), (dm2_0, ) = density_matrix(cicoeffs0, civec, obasis.nbasis) norb0, umatrix = get_naturalorbs(nbasis, dm1_0, orbs[0]) orblist = np.array(range(obasis.nbasis)) print "norb occs ", norb0.occupations assert sum(norb0.occupations) == 2.0 for i in orblist: for j in orblist: overlap = np.dot(norb0.coeffs[:, i], np.dot(olp, norb0.coeffs[:, j])) print "overlap ", overlap, i if i == j: assert abs(overlap - 1.0) < 1e-10
def makehorton(data): """ Create horton IOData object from ccData object """ hortonver = check_horton() attributes = {} if hortonver == 2: renameAttrs = {"atomnos": "numbers", "mult": "ms2", "polarizability": "polar"} inputattrs = data.__dict__ attributes = dict( (renameAttrs[oldKey], val) for (oldKey, val) in inputattrs.items() if (oldKey in renameAttrs) ) # Rest of attributes need some manipulation in data structure. if hasattr(data, "atomcoords"): # cclib parses the whole history of coordinates in the list, horton keeps the last one. attributes["coordinates"] = data.atomcoords[-1] if hasattr(data, "mocoeffs"): attributes["orb_alpha"] = data.mocoeffs[0] if len(data.mocoeffs) == 2: attributes["orb_beta"] = data.mocoeffs[1] if hasattr(data, "coreelectrons"): # cclib stores num of electrons screened out by pseudopotential # horton stores num of electrons after applying pseudopotential attributes["pseudo_numbers"] = data.atomnos - numpy.asanyarray(data.coreelectrons) if hasattr(data, "atomcharges") and ("mulliken" in data.atomcharges): attributes["mulliken_charges"] = data.atomcharges["mulliken"] if hasattr(data, "atomcharges") and ("natural" in data.atomcharges): attributes["npa_charges"] = data.atomcharges["natural"] elif hortonver == 3: # In horton 3 IOData, inputs are type-checked -- thus the bridge also verifies the types. # if coordinates are known; numpy.ndarray (size natom-by-3) if hasattr(data, "atomcoords"): attributes["atcoords"] = numpy.asanyarray(data.atomcoords)[-1] # if atomic numbers are known; numpy.ndarray (size natom) if hasattr(data, "atomnos"): attributes["atnums"] = numpy.asanyarray(data.atomnos) # if orbital coefficients known; iodata.orbitals.MolecularOrbitals if hasattr(data, "mocoeffs"): # First build a dictionary of inputs that will be passed to the constructor of # horton3's MolecularOrbitals object. moattr = { "kind": "restricted", "norba": data.nbasis, "norbb": None, # In horton 3, occupation in MOs are represented as 1's (occupied) and # 0's (unoccupied). Beta orbitals follow directly after alpha orbitals, forming # 1D array. "occs": numpy.concatenate( numpy.ones(data.homos[0]), numpy.zeros(data.nbasis - data.homos[0]) ), "coeffs": data.mocoeffs[0], "energies": None, "irreps": None, } # and if unrestricted: if len(mocoeffs) == 2: moattr["kind"] = "unrestricted" moattr["norbb"] = data.nbasis moattr["coeffs"].append(data.mocoeffs[1].T) moattr["occs"].append( numpy.concatenate( numpy.ones(data.homos[1]), numpy.zeros(data.nbasis - data.homos[1]), ) ) # Then construct MolecularOrbitals object attributes["mo"] = MolecularOrbitals(**moattr) # if multiplicity known; float / should not be set when mocoeffs present # Refer to IOData code: # https://github.com/theochem/iodata/blob/b36513d162f99b57264005583701c6987037839c/iodata/iodata.py#L174 if ( hasattr(data, "mult") and not hasattr(data, "mocoeffs") ): attributes["spinpol"] = data.mult - 1 # horton has 2S+1, iodata has 2S # if pseudopotentials exist; numpy.ndarray (size natom) if hasattr(data, "coreelectrons"): attributes["atcorenums"] = data.atomnos - numpy.asanyarray(data.coreelectrons) # if mulliken charges are known; dict of numpy.ndarrays (size natom) if hasattr(data, "atomcharges"): attributes["atcharges"] = data.atomcharges return IOData(**attributes) # Pass collected attributes into IOData constructor
def run_extensive_pop(fchkfile, hdf5file): ref_charges = IOData.from_file(fchkfile).numbers f = h5py.File('quasi_results.hdf5', 'r') g = h5py.File('pop_results.hdf5', 'w') quasitype_list = ['quasi', 'newquasi'] aao_list = ['aambs', 'ano-rcc', 'minao', 'sto-6g'] orbtype_list = ['quambo','quao','iao 1','iao 2', 'simple'] for aao in aao_list: horton_data = wrapper_horton(fchkfile, aao+'.gbs') print aao for quasitype in quasitype_list: for orbtype in orbtype_list: pops = [np.zeros(ref_charges.size) for i in range(1+int(orbtype!='simple'))] print quasitype, orbtype for index, coeff_ab_mo, olp_ab_ab, olp_cao_ab, olp_cao_cao, occupations, basis_map in zip(range(2), *horton_data[:6]): if quasitype == 'quasi': quasi = QuasiTransformation(coeff_ab_mo, olp_ab_ab, olp_cao_ab, olp_cao_cao, occupations.astype(bool)) elif quasitype == 'newquasi': quasi = NewQuasiTransformation(coeff_ab_mo, olp_ab_ab, olp_cao_ab, olp_cao_cao, occupations.astype(bool)) try: coeff_ab_quasi = f['/'.join([aao, str(index), quasitype, orbtype, 'not_orth'])][:] except KeyError: print '/'.join([aao, str(index), quasitype, orbtype, 'not_orth']) print f['/'.join([aao])].keys() print f['/'.join([aao, str(index)])].keys() print f['/'.join([aao, str(index), quasitype])].keys() print f['/'.join([aao, str(index), quasitype, orbtype])].keys() # orthogonalize if orbtype == 'simple': tmp_olp_ab_ab = quasi.olp_ab_ab coeff_ab_omo = quasi.coeff_ab_omo olp_quasi_quasi = coeff_ab_quasi.T.dot(tmp_olp_ab_ab).dot(coeff_ab_quasi) olp_quasi_omo = coeff_ab_quasi.T.dot(tmp_olp_ab_ab).dot(coeff_ab_omo) print np.linalg.matrix_rank(coeff_ab_quasi) print np.linalg.matrix_rank(olp_quasi_quasi) print 'xxxxxxxxxxxxxxx' coeff_quasi_omo = project(olp_quasi_quasi, olp_quasi_omo) print olp_quasi_omo.shape print np.diag(olp_quasi_omo.T.dot(coeff_quasi_omo)) #print coeff_quasi_omo.T.dot(olp_quasi_quasi).dot(coeff_quasi_omo) occ = occupations[occupations>0] pops[0] += Mulliken(coeff_quasi_omo, occ, olp_quasi_quasi, len(set(basis_map)), basis_map).get_population() continue coeff_ab_oquasi = f['/'.join([aao, str(index), quasitype, orbtype, 'orth'])][:] if orbtype == 'iao 2': tmp_olp_ab_ab = np.zeros([quasi.num_ab+quasi.num_aao]*2) tmp_olp_ab_ab[:quasi.num_ab] = np.hstack((quasi.olp_ab_ab, quasi.olp_ab_aao)) tmp_olp_ab_ab[quasi.num_ab:] = np.hstack((quasi.olp_aao_ab, quasi.olp_aao_aao)) coeff_ab_omo = np.vstack((quasi.coeff_ab_omo, np.zeros([quasi.num_aao, quasi.num_omo]))) else: tmp_olp_ab_ab = quasi.olp_ab_ab coeff_ab_omo = quasi.coeff_ab_omo for i, coeff in enumerate([coeff_ab_quasi, coeff_ab_oquasi]): olp_quasi_quasi = coeff.T.dot(tmp_olp_ab_ab).dot(coeff) olp_quasi_omo = coeff.T.dot(tmp_olp_ab_ab).dot(coeff_ab_omo) coeff_quasi_omo = project(olp_quasi_quasi, olp_quasi_omo) occ = occupations[occupations>0] pops[i] += Mulliken(coeff_quasi_omo, occ, olp_quasi_quasi, len(set(basis_map)), basis_map).get_population() print '/'.join([aao, str(index), quasitype, orbtype, 'not_orth']) print pops g.create_dataset('/'.join([aao, str(index), quasitype, orbtype, 'not_orth']), data=ref_charges-pops[0]) if orbtype != 'simple': g.create_dataset('/'.join([aao, str(index), quasitype, orbtype, 'orth']), data=ref_charges-pops[1])
def check_h3_os_hfs(scf_solver): fn_fchk = context.get_fn('test/h3_hfs_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)} libxc_term = ULibXCLDA('x') terms1 = [ UTwoIndexTerm(kin, 'kin'), UDirectTerm(er, 'hartree'), UGridGroup(mol.obasis, grid, [libxc_term]), UTwoIndexTerm(na, 'ne'), ] ham1 = UEffHam(terms1, external) builtin_term = UDiracExchange() terms2 = [ UTwoIndexTerm(kin, 'kin'), UDirectTerm(er, 'hartree'), UGridGroup(mol.obasis, grid, [builtin_term]), UTwoIndexTerm(na, 'ne'), ] ham2 = UEffHam(terms2, external) # Compare the potential computed by libxc with the builtin implementation energy1, focks1 = helper_compute(ham1, mol.lf, mol.exp_alpha, mol.exp_beta) energy2, focks2 = helper_compute(ham2, mol.lf, mol.exp_alpha, mol.exp_beta) libxc_pot = ham1.cache.load('pot_libxc_lda_x_both')[:, 0] builtin_pot = ham2.cache.load('pot_x_dirac_alpha') # Libxc apparently approximates values of the potential below 1e-4 with zero. assert abs(libxc_pot - builtin_pot).max() < 1e-4 # Check of the libxc energy matches our implementation assert abs(energy1 - energy2) < 1e-10 ex1 = ham1.cache['energy_libxc_lda_x'] ex2 = ham2.cache['energy_x_dirac'] assert abs(ex1 - ex2) < 1e-10 # The convergence should be reasonable, not perfect because of limited # precision in Gaussian fchk file: assert convergence_error_eigen(ham1, mol.lf, olp, mol.exp_alpha, mol.exp_beta) < 1e-5 assert convergence_error_eigen(ham2, mol.lf, olp, mol.exp_alpha, mol.exp_beta) < 1e-5 occ_model = AufbauOccModel(2, 1) for ham in ham1, ham2: # Converge from scratch 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([ -4.93959157E-01, -1.13961330E-01, 2.38730924E-01, 7.44216538E-01, 8.30143356E-01, 1.46613581E+00 ]) assert abs(mol.exp_alpha.energies - expected_energies).max() < 1e-5 expected_energies = np.array([ -4.34824166E-01, 1.84114514E-04, 3.24300545E-01, 7.87622756E-01, 9.42415831E-01, 1.55175481E+00 ]) assert abs(mol.exp_beta.energies - expected_energies).max() < 1e-5 ham.compute_energy() # compare with g09 assert abs(ham.cache['energy_ne'] - -6.832069993374E+00) < 1e-5 assert abs(ham.cache['energy_kin'] - 1.870784279014E+00) < 1e-5 assert abs(ham.cache['energy'] - -1.412556114057104E+00) < 1e-5 assert abs(ham.cache['energy_nn'] - 1.8899186021) < 1e-8 assert abs(ham1.cache['energy_hartree'] + ham1.cache['energy_libxc_lda_x'] - 1.658810998195E+00) < 1e-6 assert abs(ham2.cache['energy_hartree'] + ham2.cache['energy_x_dirac'] - 1.658810998195E+00) < 1e-6
def check_n2_cs_hfs(scf_solver): fn_fchk = context.get_fn('test/n2_hfs_sto3g.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)} libxc_term = RLibXCLDA('x') terms1 = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RGridGroup(mol.obasis, grid, [libxc_term]), RTwoIndexTerm(na, 'ne'), ] ham1 = REffHam(terms1, external) builtin_term = RDiracExchange() terms2 = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RGridGroup(mol.obasis, grid, [builtin_term]), RTwoIndexTerm(na, 'ne'), ] ham2 = REffHam(terms2, external) # Compare the potential computed by libxc with the builtin implementation energy1, focks1 = helper_compute(ham1, mol.lf, mol.exp_alpha) energy2, focks2 = helper_compute(ham2, mol.lf, mol.exp_alpha) libxc_pot = ham1.cache.load('pot_libxc_lda_x_alpha') builtin_pot = ham2.cache.load('pot_x_dirac_alpha') # Libxc apparently approximates values of the potential below 1e-4 with zero. assert abs(libxc_pot - builtin_pot).max() < 1e-4 # Check of the libxc energy matches our implementation assert abs(energy1 - energy2) < 1e-10 ex1 = ham1.cache['energy_libxc_lda_x'] ex2 = ham2.cache['energy_x_dirac'] assert abs(ex1 - ex2) < 1e-10 # The convergence should be reasonable, not perfect because of limited # precision in Gaussian fchk file: assert convergence_error_eigen(ham1, mol.lf, olp, mol.exp_alpha) < 1e-5 assert convergence_error_eigen(ham2, mol.lf, olp, mol.exp_alpha) < 1e-5 occ_model = AufbauOccModel(7) for ham in ham1, ham2: # Converge from scratch check_solve(ham, scf_solver, occ_model, mol.lf, olp, kin, na, mol.exp_alpha) # test orbital energies expected_energies = np.array([ -1.37107053E+01, -1.37098006E+01, -9.60673085E-01, -3.57928483E-01, -3.16017655E-01, -3.16017655E-01, -2.12998316E-01, 6.84030479E-02, 6.84030479E-02, 7.50192517E-01, ]) assert abs(mol.exp_alpha.energies - expected_energies).max() < 3e-5 ham.compute_energy() assert abs(ham.cache['energy_ne'] - -2.981579553570E+02) < 1e-5 assert abs(ham.cache['energy_kin'] - 1.061620887711E+02) < 1e-5 assert abs(ham.cache['energy'] - -106.205213597) < 1e-4 assert abs(ham.cache['energy_nn'] - 23.3180604505) < 1e-8 assert abs(ham1.cache['energy_hartree'] + ham1.cache['energy_libxc_lda_x'] - 6.247259253877E+01) < 1e-4 assert abs(ham2.cache['energy_hartree'] + ham2.cache['energy_x_dirac'] - 6.247259253877E+01) < 1e-4
def check_h3_os_hfs(scf_solver): fn_fchk = context.get_fn('test/h3_hfs_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)} libxc_term = ULibXCLDA('x') terms1 = [ UTwoIndexTerm(kin, 'kin'), UDirectTerm(er, 'hartree'), UGridGroup(mol.obasis, grid, [libxc_term]), UTwoIndexTerm(na, 'ne'), ] ham1 = UEffHam(terms1, external) builtin_term = UDiracExchange() terms2 = [ UTwoIndexTerm(kin, 'kin'), UDirectTerm(er, 'hartree'), UGridGroup(mol.obasis, grid, [builtin_term]), UTwoIndexTerm(na, 'ne'), ] ham2 = UEffHam(terms2, external) # Compare the potential computed by libxc with the builtin implementation energy1, focks1 = helper_compute(ham1, mol.lf, mol.exp_alpha, mol.exp_beta) energy2, focks2 = helper_compute(ham2, mol.lf, mol.exp_alpha, mol.exp_beta) libxc_pot = ham1.cache.load('pot_libxc_lda_x_both')[:,0] builtin_pot = ham2.cache.load('pot_x_dirac_alpha') # Libxc apparently approximates values of the potential below 1e-4 with zero. assert abs(libxc_pot - builtin_pot).max() < 1e-4 # Check of the libxc energy matches our implementation assert abs(energy1 - energy2) < 1e-10 ex1 = ham1.cache['energy_libxc_lda_x'] ex2 = ham2.cache['energy_x_dirac'] assert abs(ex1 - ex2) < 1e-10 # The convergence should be reasonable, not perfect because of limited # precision in Gaussian fchk file: assert convergence_error_eigen(ham1, mol.lf, olp, mol.exp_alpha, mol.exp_beta) < 1e-5 assert convergence_error_eigen(ham2, mol.lf, olp, mol.exp_alpha, mol.exp_beta) < 1e-5 occ_model = AufbauOccModel(2, 1) for ham in ham1, ham2: # Converge from scratch 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([ -4.93959157E-01, -1.13961330E-01, 2.38730924E-01, 7.44216538E-01, 8.30143356E-01, 1.46613581E+00 ]) assert abs(mol.exp_alpha.energies - expected_energies).max() < 1e-5 expected_energies = np.array([ -4.34824166E-01, 1.84114514E-04, 3.24300545E-01, 7.87622756E-01, 9.42415831E-01, 1.55175481E+00 ]) assert abs(mol.exp_beta.energies - expected_energies).max() < 1e-5 ham.compute_energy() # compare with g09 assert abs(ham.cache['energy_ne'] - -6.832069993374E+00) < 1e-5 assert abs(ham.cache['energy_kin'] - 1.870784279014E+00) < 1e-5 assert abs(ham.cache['energy'] - -1.412556114057104E+00) < 1e-5 assert abs(ham.cache['energy_nn'] - 1.8899186021) < 1e-8 assert abs(ham1.cache['energy_hartree'] + ham1.cache['energy_libxc_lda_x'] - 1.658810998195E+00) < 1e-6 assert abs(ham2.cache['energy_hartree'] + ham2.cache['energy_x_dirac'] - 1.658810998195E+00) < 1e-6