def test_cgf_overlap(self): """ Test kinetic integrals for contracted Gaussians Sij = <cgf_i | cgf_j> """ # construct integrator object integrator = PyQInt() # build hydrogen molecule mol = Molecule("H2") mol.add_atom('H', 0.0, 0.0, 0.0) mol.add_atom('H', 0.0, 0.0, 1.4) cgfs, nuclei = mol.build_basis('sto3g') S = np.zeros((2, 2)) S[0, 0] = integrator.overlap(cgfs[0], cgfs[0]) S[0, 1] = S[1, 0] = integrator.overlap(cgfs[0], cgfs[1]) S[1, 1] = integrator.overlap(cgfs[1], cgfs[1]) S11 = 1.0 S12 = 0.65931845 np.testing.assert_almost_equal(S[0, 0], S11, 4) np.testing.assert_almost_equal(S[1, 1], S11, 4) np.testing.assert_almost_equal(S[0, 1], S12, 4)
def test_cgf_kinetic(self): """ Test kinetic integrals for contracted Gaussians Tij = <cgf_i | -1/2 nabla^{2} | cgf_j> """ # construct integrator object integrator = PyQInt() # build hydrogen molecule mol = Molecule("H2") mol.add_atom('H', 0.0, 0.0, 0.0) mol.add_atom('H', 0.0, 0.0, 1.4) cgfs, nuclei = mol.build_basis('sto3g') T = np.zeros((2, 2)) T[0, 0] = integrator.kinetic(cgfs[0], cgfs[0]) T[0, 1] = T[1, 0] = integrator.kinetic(cgfs[0], cgfs[1]) T[1, 1] = integrator.kinetic(cgfs[1], cgfs[1]) T11 = 0.7600315809249878 T12 = 0.2364544570446014 np.testing.assert_almost_equal(T[0, 0], T11, 4) np.testing.assert_almost_equal(T[1, 1], T11, 4) np.testing.assert_almost_equal(T[0, 1], T12, 4)
def test_cgf_nuclear(self): """ Test nuclear attraction integrals for contracted Gaussians V^{(c)}_ij = <cgf_i | -Zc / |r-Rc| | cgf_j> """ integrator = PyQInt() # build hydrogen molecule mol = Molecule("H2") mol.add_atom('H', 0.0, 0.0, 0.0) mol.add_atom('H', 0.0, 0.0, 1.4) cgfs, nuclei = mol.build_basis('sto3g') V1 = np.zeros((2,2)) V1[0,0] = integrator.nuclear(cgfs[0], cgfs[0], cgfs[0].p, 1) V1[0,1] = V1[1,0] = integrator.nuclear(cgfs[0], cgfs[1], cgfs[0].p, 1) V1[1,1] = integrator.nuclear(cgfs[1], cgfs[1], cgfs[0].p, 1) V2 = np.zeros((2,2)) V2[0,0] = integrator.nuclear(cgfs[0], cgfs[0], cgfs[1].p, 1) V2[0,1] = V2[1,0] = integrator.nuclear(cgfs[0], cgfs[1], cgfs[1].p, 1) V2[1,1] = integrator.nuclear(cgfs[1], cgfs[1], cgfs[1].p, 1) V11 = -1.2266135215759277 V12 = -0.5974172949790955 V22 = -0.6538270711898804 np.testing.assert_almost_equal(V1[0,0], V11, 4) np.testing.assert_almost_equal(V1[1,1], V22, 4) np.testing.assert_almost_equal(V1[0,1], V12, 4) np.testing.assert_almost_equal(V2[0,0], V22, 4) np.testing.assert_almost_equal(V2[1,1], V11, 4) np.testing.assert_almost_equal(V2[0,1], V12, 4)
def testFunctionsCGF(self): """ Test getting amplitude from CGF """ # construct integrator object integrator = PyQInt() # get compile info compile_info = integrator.get_compile_info() # build hydrogen molecule mol = Molecule() mol.add_atom('H', 0.0, 0.0, 0.0) cgfs, nuclei = mol.build_basis('sto3g') # test values at these coordinates coords = [] for x in np.linspace(0, 10, 10): coords.append([x, x, x]) # results ans = [ 6.2825e-01, 7.1229e-02, 6.8672e-03, 3.0000e-04, 3.7662e-06, 1.3536e-08, 1.3927e-11, 4.1021e-15, 3.4591e-19, 8.3505e-24 ] # test for each coord amps = [] for i, coord in enumerate(coords): amp = cgfs[0].get_amp(coord) amps.append(amp) np.testing.assert_almost_equal(amps, ans, 4)
def test_cgf_repulsion(self): """ Test two-electron integrals for contracted Gaussians (ij|kl) = <cgf_i cgf_j | r_ij | cgf_k cgf_l> """ # construct integrator object integrator = PyQInt() # build hydrogen molecule mol = Molecule("H2") mol.add_atom('H', 0.0, 0.0, 0.0) mol.add_atom('H', 0.0, 0.0, 1.4) cgfs, nuclei = mol.build_basis('sto3g') T1111 = integrator.repulsion(cgfs[0], cgfs[0], cgfs[0], cgfs[0]) T1122 = integrator.repulsion(cgfs[0], cgfs[0], cgfs[1], cgfs[1]) T1112 = integrator.repulsion(cgfs[0], cgfs[0], cgfs[0], cgfs[1]) T2121 = integrator.repulsion(cgfs[1], cgfs[0], cgfs[1], cgfs[0]) T1222 = integrator.repulsion(cgfs[0], cgfs[1], cgfs[1], cgfs[1]) T2211 = integrator.repulsion(cgfs[1], cgfs[1], cgfs[0], cgfs[0]) np.testing.assert_almost_equal(T1111, 0.7746056914329529, 4) np.testing.assert_almost_equal(T1122, 0.5696758031845093, 4) np.testing.assert_almost_equal(T1112, 0.4441076656879812, 4) np.testing.assert_almost_equal(T2121, 0.2970285713672638, 4) # test similarity between two-electron integrals np.testing.assert_almost_equal(T1222, T1112, 4) np.testing.assert_almost_equal(T1122, T2211, 4)
def testDerivH2(self): """ Test Derivatives of dihydrogen """ # build integrator object integrator = PyQInt() # build hydrogen molecule mol = Molecule('H2') mol.add_atom('H', -0.5, 0.0, 0.0) mol.add_atom('H', 0.5, 0.0, 0.0) cgfs, nuclei = mol.build_basis('sto3g') fx1 = integrator.nuclear_deriv(cgfs[0], cgfs[0], nuclei[0][0], nuclei[0][1], nuclei[0][0], 0) fx2 = integrator.nuclear_deriv(cgfs[1], cgfs[1], nuclei[0][0], nuclei[0][1], nuclei[0][0], 0) ans1 = calculate_force_finite_difference(cgfs[0], cgfs[0], nuclei[0][0], nuclei[0][1], 0) ans2 = calculate_force_finite_difference(cgfs[1], cgfs[1], nuclei[0][0], nuclei[0][1], 0) np.testing.assert_almost_equal(fx1, ans1, 4) np.testing.assert_almost_equal(fx2, ans2, 4) # assert that the nuclear gradient in the x direction is zero because the # basis functions spawn from this atom self.assertTrue(np.abs(fx1) < 1e-8) # assert that the nuclear gradient has a meaningful number self.assertTrue(np.abs(fx2) > 1e-1) fx3 = integrator.nuclear_deriv(cgfs[0], cgfs[0], nuclei[1][0], nuclei[1][1], nuclei[1][0], 0) fx4 = integrator.nuclear_deriv(cgfs[1], cgfs[1], nuclei[1][0], nuclei[1][1], nuclei[1][0], 0) ans3 = calculate_force_finite_difference(cgfs[0], cgfs[0], nuclei[1][0], nuclei[1][1], 0) ans4 = calculate_force_finite_difference(cgfs[1], cgfs[1], nuclei[1][0], nuclei[1][1], 0) np.testing.assert_almost_equal(fx3, ans3, 4) np.testing.assert_almost_equal(fx4, ans4, 4) fy1 = integrator.nuclear_deriv(cgfs[0], cgfs[0], nuclei[0][0], nuclei[0][1], nuclei[0][0], 1) fy2 = integrator.nuclear_deriv(cgfs[1], cgfs[1], nuclei[0][0], nuclei[0][1], nuclei[0][0], 1) ans5 = calculate_force_finite_difference(cgfs[0], cgfs[0], nuclei[0][0], nuclei[0][1], 1) ans6 = calculate_force_finite_difference(cgfs[1], cgfs[1], nuclei[0][0], nuclei[0][1], 1) np.testing.assert_almost_equal(fy1, ans5, 4) np.testing.assert_almost_equal(fy2, ans6, 4)
def test_integrals_h2(self): """ Test automatic integral evaluation for hydrogen molecule """ # construct integrator object integrator = PyQInt() # build hydrogen molecule mol = Molecule() mol.add_atom('H', 0.0, 0.0, 0.0) mol.add_atom('H', 0.0, 0.0, 1.4) cgfs, nuclei = mol.build_basis('sto3g') # evaluate all integrals ncpu = multiprocessing.cpu_count() S, T, V, teint = integrator.build_integrals(cgfs, nuclei, npar=ncpu, verbose=False) # overlap integrals S_result = np.matrix([[1.0, 0.65931845], [0.65931845, 1.0]]) # kinetic integrals T_result = np.matrix([[0.7600315809249878, 0.2364544570446014], [0.2364544570446014, 0.7600315809249878]]) # nuclear attraction integrals V1_result = np.matrix([[-1.2266135215759277, -0.5974172949790955], [-0.5974172949790955, -0.6538270711898804]]) V2_result = np.matrix([[-0.6538270711898804, -0.5974172949790955], [-0.5974172949790955, -1.2266135215759277]]) V_result = V1_result + V2_result # two-electron integrals T1111 = 0.7746056914329529 T1122 = 0.5696758031845093 T1112 = 0.4441076219081878 T1212 = 0.2970285713672638 # perform tests np.testing.assert_almost_equal(S, S_result, 4) np.testing.assert_almost_equal(T, T_result, 4) np.testing.assert_almost_equal(V, V_result, 4) np.testing.assert_almost_equal(teint[integrator.teindex(0, 0, 0, 0)], T1111, 4) np.testing.assert_almost_equal(teint[integrator.teindex(0, 0, 1, 1)], T1122, 4) np.testing.assert_almost_equal(teint[integrator.teindex(0, 0, 0, 1)], T1112, 4) np.testing.assert_almost_equal(teint[integrator.teindex(0, 1, 0, 1)], T1212, 4)
def testDerivH2(self): """ Test Derivatives of dihydrogen """ # build integrator object integrator = PyQInt() # build hydrogen molecule mol = Molecule('H2') mol.add_atom('H', -0.5, 0.0, 0.0) mol.add_atom('H', 0.5, 0.0, 0.0) cgfs, nuclei = mol.build_basis('sto3g') # calculate derivative towards H1 in the x-direction fx1 = integrator.repulsion_deriv(cgfs[0], cgfs[0], cgfs[0], cgfs[0], nuclei[0][0], 0) fx2 = integrator.repulsion_deriv(cgfs[1], cgfs[1], cgfs[1], cgfs[1], nuclei[0][0], 0) # mol | nuc_id | cgf_id1 | cgf_id2 | cgf_id3 | cgf_id4 | coord ans1 = calculate_force_finite_difference(mol, 0, 0, 0, 0, 0, 0) ans2 = calculate_force_finite_difference(mol, 0, 1, 1, 1, 1, 0) # assert that the repulsion of two CGFs that spawn from # the same nucleus will not change in energy due to a # change of the nucleus coordinates np.testing.assert_almost_equal(fx1, ans1, 4) np.testing.assert_almost_equal(fx1, 0.0, 4) np.testing.assert_almost_equal(fx2, ans2, 4) np.testing.assert_almost_equal(fx2, 0.0, 4) # assert that the cross-terms will change fx3 = integrator.repulsion_deriv(cgfs[0], cgfs[0], cgfs[1], cgfs[1], nuclei[0][0], 0) fx4 = integrator.repulsion_deriv(cgfs[0], cgfs[0], cgfs[1], cgfs[1], nuclei[1][0], 0) fx5 = integrator.repulsion_deriv(cgfs[1], cgfs[0], cgfs[1], cgfs[0], nuclei[0][0], 0) fx6 = integrator.repulsion_deriv(cgfs[1], cgfs[0], cgfs[1], cgfs[0], nuclei[1][0], 0) # mol | nuc_id | cgf_id1 | cgf_id2 | cgf_id3 | cgf_id4 | coord ans3 = calculate_force_finite_difference(mol, 0, 0, 0, 1, 1, 0) ans4 = calculate_force_finite_difference(mol, 1, 0, 0, 1, 1, 0) ans5 = calculate_force_finite_difference(mol, 0, 1, 0, 1, 0, 0) ans6 = calculate_force_finite_difference(mol, 1, 1, 0, 1, 0, 0) np.testing.assert_almost_equal(fx3, ans3, 4) np.testing.assert_almost_equal(fx4, ans4, 4) np.testing.assert_almost_equal(fx5, ans5, 4) np.testing.assert_almost_equal(fx6, ans6, 4)
def test_integrals_h2o_openmp_sto3g(self): """ Test OpenMP integral evaluation for H2O using sto-3g basis set """ # construct integrator object integrator = PyQInt() # build water molecule mol = Molecule("H2O") mol.add_atom('H', 0.7570, 0.5860, 0.0) mol.add_atom('H', -0.7570, 0.5860, 0.0) mol.add_atom('O', 0.0, 0.0, 0.0) cgfs, nuclei = mol.build_basis('sto3g') # evaluate all integrals ncpu = multiprocessing.cpu_count() S, T, V, teint = integrator.build_integrals_openmp(cgfs, nuclei) # load results from npy files S_result = np.load(os.path.join(os.path.dirname(__file__), 'results', 'h2o_overlap_sto3g.npy')) T_result = np.load(os.path.join(os.path.dirname(__file__), 'results', 'h2o_kinetic_sto3g.npy')) V_result = np.load(os.path.join(os.path.dirname(__file__), 'results', 'h2o_nuclear_sto3g.npy')) teint_result = np.load(os.path.join(os.path.dirname(__file__), 'results', 'h2o_teint_sto3g.npy')) # assessment self.assertEqual(len(cgfs), 7) self.assertEqual(S.shape[0], S.shape[1]) self.assertEqual(S.shape[0], len(cgfs)) np.testing.assert_almost_equal(S, S_result, 4) np.testing.assert_almost_equal(T, T_result, 4) np.testing.assert_almost_equal(V, V_result, 4) np.testing.assert_almost_equal(teint, teint_result, 4)
def testPlotGrid(self): """ Test plotting of 1b2 molecular orbital of H2O """ # coefficients coeff = [ 8.37612e-17, -2.73592e-16, -0.713011, -1.8627e-17, 9.53496e-17, -0.379323, 0.379323 ] # construct integrator object integrator = PyQInt() # build water molecule mol = Molecule('H2O') mol.add_atom('O', 0.0, 0.0, 0.0) mol.add_atom('H', 0.7570, 0.5860, 0.0) mol.add_atom('H', -0.7570, 0.5860, 0.0) cgfs, nuclei = mol.build_basis('sto3g') # build grid x = np.linspace(-2, 2, 50) y = np.linspace(-2, 2, 50) xx, yy = np.meshgrid(x, y) zz = np.zeros(len(x) * len(y)) grid = np.vstack([xx.flatten(), yy.flatten(), zz]).reshape(3, -1).T res = integrator.plot_wavefunction(grid, coeff, cgfs).reshape( (len(y), len(x))) ans = np.load( os.path.join(os.path.dirname(__file__), 'results', 'h2o_orb_1b2.npy')) np.testing.assert_almost_equal(res, ans, 8)
def testHartreeFockForcesCore(self): """ Test Hartree-Fock calculation on water using STO-3G basis set """ mol = Molecule() mol.add_atom('O', 0.0, 0.0, 0.0) mol.add_atom('H', 0.7570, 0.5860, 0.0) mol.add_atom('H', -0.7570, 0.5860, 0.0) basis = 'sto3g' # calculate forces using analytical derivatives solver = HF() res = solver.rhf(mol, basis, calc_forces=False) # calculate forces via routines forces = np.zeros((len(mol.atoms), 3)) for i in range(0, len(mol.atoms)): # loop over nuclei for j in range(0, 3): # loop over directions forces[i, j] = np.sum(res['density'] * solver.rhf_force_core(mol, basis, i, j)) # calculate forces using finite difference forces_ans = calculate_forces_core_finite_difference(mol) np.testing.assert_almost_equal(forces, forces_ans)
def test_strings(self): """ Test automatic integral evaluation for hydrogen molecule """ # construct integrator object integrator = PyQInt() # build hydrogen molecule mol = Molecule('H2') mol.add_atom('H', 0.0, 0.0, 0.0) mol.add_atom('H', 0.0, 0.0, 1.4) cgfs, nuclei = mol.build_basis('sto3g') ans = "CGF; R=(0.000000,0.000000,0.000000)\n" ans += " 01 | GTO : c=0.154329, alpha=3.425251, l=0, m=0, n=0, R=(0.000000,0.000000,0.000000)\n" ans += " 02 | GTO : c=0.535328, alpha=0.623914, l=0, m=0, n=0, R=(0.000000,0.000000,0.000000)\n" ans += " 03 | GTO : c=0.444635, alpha=0.168855, l=0, m=0, n=0, R=(0.000000,0.000000,0.000000)\n" self.assertEqual(str(cgfs[0]), ans) ans = "Molecule: H2\n" ans += " H (0.000000,0.000000,0.000000)\n" ans += " H (0.000000,0.000000,1.400000)\n" self.assertEqual(str(mol), ans)
def testHartreeFockWater(self): """ Test Hartree-Fock calculation on water using STO-3G basis set """ mol = Molecule() mol.add_atom('O', 0.0, 0.0, 0.0) mol.add_atom('H', 0.7570, 0.5860, 0.0) mol.add_atom('H', -0.7570, 0.5860, 0.0) energy = perform_hf(mol) np.testing.assert_almost_equal(energy, -73.21447132, 4)
def testNuclearRepulsionDerivatives(self): """ Test Hartree-Fock calculation on water using STO-3G basis set """ mol = Molecule() mol.add_atom('O', 0.0, 0.0, 0.0) mol.add_atom('H', 0.7570, 0.5860, 0.0) mol.add_atom('H', -0.7570, 0.5860, 0.0) cgfs, nuclei = mol.build_basis('sto3g') forces_fd = calculate_deriv_nuclear_repulsion_finite_difference(mol) forces = np.zeros(forces_fd.shape) for i in range(0, len(mol.atoms)): # loop over nuclei for j in range(0, 3): # loop over directions forces[i, j] = deriv_nuclear_repulsion(nuclei, i, j) np.testing.assert_almost_equal(forces, forces_fd, 4)
def testDerivH2O(self): """ Test Derivatives of dihydrogen """ # build integrator object integrator = PyQInt() # build hydrogen molecule mol = Molecule() mol.add_atom('O', 0.0, 0.0, 0.0) mol.add_atom('H', 0.7570, 0.5860, 0.0) mol.add_atom('H', -0.7570, 0.5860, 0.0) cgfs, nuclei = mol.build_basis('sto3g') # calculate derivative towards H1 in the x-direction fx1 = integrator.overlap_deriv(cgfs[2], cgfs[2], nuclei[1][0], 0) # px fx2 = integrator.overlap_deriv(cgfs[2], cgfs[3], nuclei[1][0], 0) # py ans1 = calculate_force_finite_difference(mol, 1, 2, 2, 0) ans2 = calculate_force_finite_difference(mol, 1, 3, 3, 0) # assert that the overlap of two CGFs that spawn from # the same nucleus will not change in energy due to a # change of the nucleus coordinates np.testing.assert_almost_equal(fx1, ans1, 4) np.testing.assert_almost_equal(fx2, ans2, 4) # assert that the cross-terms will change fx3 = integrator.overlap_deriv(cgfs[2], cgfs[5], nuclei[1][0], 0) fx4 = integrator.overlap_deriv(cgfs[2], cgfs[5], nuclei[1][0], 0) ans3 = calculate_force_finite_difference(mol, 1, 2, 5, 0) ans4 = calculate_force_finite_difference(mol, 1, 2, 5, 0) np.testing.assert_almost_equal(fx3, ans3, 4) self.assertFalse(fx3 == 0.0) np.testing.assert_almost_equal(fx4, ans4, 4) self.assertFalse(fx4 == 0.0)
def testDerivH2O(self): """ Test Derivatives of water """ # build integrator object integrator = PyQInt() # build hydrogen molecule mol = Molecule() mol.add_atom('O', 0.0, 0.0, 0.0) mol.add_atom('H', 0.7570, 0.5860, 0.0) mol.add_atom('H', -0.7570, 0.5860, 0.0) cgfs, nuclei = mol.build_basis('sto3g') # calculate derivative of 2s AO on oxygen towards H1 in the x-direction fx1 = integrator.repulsion_deriv(cgfs[2], cgfs[2], cgfs[2], cgfs[2], nuclei[1][0], 0) # px fx2 = integrator.repulsion_deriv(cgfs[2], cgfs[3], cgfs[3], cgfs[3], nuclei[1][0], 0) # py ans1 = calculate_force_finite_difference(mol, 1, 2, 2, 2, 2, 0) ans2 = calculate_force_finite_difference(mol, 1, 3, 3, 3, 3, 0) # assert that the repulsion of two CGFs that spawn from # the same nucleus will not change in energy due to a # change of the nucleus coordinates np.testing.assert_almost_equal(fx1, ans1, 4) np.testing.assert_almost_equal(fx2, ans2, 4) # assert that the cross-terms will change fx3 = integrator.repulsion_deriv(cgfs[3], cgfs[3], cgfs[5], cgfs[5], nuclei[0][0], 0) fx4 = integrator.repulsion_deriv(cgfs[3], cgfs[3], cgfs[5], cgfs[5], nuclei[1][0], 0) fx5 = integrator.repulsion_deriv(cgfs[5], cgfs[3], cgfs[5], cgfs[3], nuclei[0][0], 0) fx6 = integrator.repulsion_deriv(cgfs[3], cgfs[5], cgfs[3], cgfs[5], nuclei[1][0], 0) # mol | nuc_id | cgf_id1 | cgf_id2 | cgf_id3 | cgf_id4 | coord ans3 = calculate_force_finite_difference(mol, 0, 3, 3, 5, 5, 0) ans4 = calculate_force_finite_difference(mol, 1, 3, 3, 5, 5, 0) ans5 = calculate_force_finite_difference(mol, 0, 5, 3, 5, 3, 0) ans6 = calculate_force_finite_difference(mol, 1, 3, 5, 3, 5, 0) # assert that these are non-trivial tests self.assertFalse(ans3 == 0.0) self.assertFalse(ans4 == 0.0) self.assertFalse(ans5 == 0.0) self.assertFalse(ans6 == 0.0) np.testing.assert_almost_equal(fx3, ans3, 10) np.testing.assert_almost_equal(fx4, ans4, 10) np.testing.assert_almost_equal(fx5, ans5, 10) np.testing.assert_almost_equal(fx6, ans6, 10) # assert that the cross-terms will change fx7 = integrator.repulsion_deriv(cgfs[2], cgfs[3], cgfs[5], cgfs[6], nuclei[0][0], 0) fx8 = integrator.repulsion_deriv(cgfs[2], cgfs[3], cgfs[5], cgfs[6], nuclei[1][0], 1) fx9 = integrator.repulsion_deriv(cgfs[2], cgfs[3], cgfs[5], cgfs[6], nuclei[2][0], 1) # get answers ans7 = calculate_force_finite_difference(mol, 0, 2, 3, 5, 6, 0) ans8 = calculate_force_finite_difference(mol, 1, 2, 3, 5, 6, 1) ans9 = calculate_force_finite_difference(mol, 2, 2, 3, 5, 6, 1) # assert that these are non-trivial tests self.assertFalse(ans7 == 0.0) self.assertFalse(ans8 == 0.0) self.assertFalse(ans9 == 0.0) np.testing.assert_almost_equal(fx7, ans7, 10) np.testing.assert_almost_equal(fx8, ans8, 10) np.testing.assert_almost_equal(fx9, ans9, 10)