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 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 check_vanadium_sc_hf(scf_solver): """Try to converge the SCF for the neutral vanadium atom with fixe fractional occupations. Parameters ---------- scf_solver : one of the SCFSolver types in HORTON A configured SCF solver that must be tested. """ # vanadium atoms numbers = np.array([23]) pseudo_numbers = numbers.astype(float) coordinates = np.zeros((1, 3), float) # Simple basis set obasis = get_gobasis(coordinates, numbers, 'def2-tzvpd') # Dense matrices lf = DenseLinalgFactory(obasis.nbasis) # Compute integrals olp = obasis.compute_overlap(lf) kin = obasis.compute_kinetic(lf) na = obasis.compute_nuclear_attraction(coordinates, pseudo_numbers, lf) er = obasis.compute_electron_repulsion(lf) # Setup of restricted HF Hamiltonian terms = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RExchangeTerm(er, 'x_hf'), RTwoIndexTerm(na, 'ne'), ] ham = REffHam(terms) # Define fractional occupations of interest. (Spin-compensated case) occ_model = FixedOccModel( np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5])) # Allocate orbitals and make the initial guess exp_alpha = lf.create_expansion(obasis.nbasis) guess_core_hamiltonian(olp, kin, na, exp_alpha) # SCF test check_solve(ham, scf_solver, occ_model, lf, olp, kin, na, exp_alpha)
def check_vanadium_sc_hf(scf_solver): """Try to converge the SCF for the neutral vanadium atom with fixe fractional occupations. Parameters ---------- scf_solver : one of the SCFSolver types in HORTON A configured SCF solver that must be tested. """ # vanadium atoms numbers = np.array([23]) pseudo_numbers = numbers.astype(float) coordinates = np.zeros((1, 3), float) # Simple basis set obasis = get_gobasis(coordinates, numbers, 'def2-tzvpd') # Dense matrices lf = DenseLinalgFactory(obasis.nbasis) # Compute integrals olp = obasis.compute_overlap(lf) kin = obasis.compute_kinetic(lf) na = obasis.compute_nuclear_attraction(coordinates, pseudo_numbers, lf) er = obasis.compute_electron_repulsion(lf) # Setup of restricted HF Hamiltonian terms = [ RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RExchangeTerm(er, 'x_hf'), RTwoIndexTerm(na, 'ne'), ] ham = REffHam(terms) # Define fractional occupations of interest. (Spin-compensated case) occ_model = FixedOccModel(np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5])) # Allocate orbitals and make the initial guess exp_alpha = lf.create_expansion(obasis.nbasis) guess_core_hamiltonian(olp, kin, na, exp_alpha) # SCF test check_solve(ham, scf_solver, occ_model, lf, olp, kin, na, exp_alpha)
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 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 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