示例#1
0
def test_ao2mo_hand_against_pyscf_rhf_partial():

    mol = molecules_pyscf.molecule_physicists_water_sto3g()
    mol.build()

    mf = pyscf.scf.RHF(mol)
    mf.kernel()
    C = fix_mocoeffs_shape(mf.mo_coeff)
    occupations = occupations_from_pyscf_mol(mol, C)
    nocc, nvirt, _, _ = occupations
    nmo = nocc + nvirt
    ntransforms = 2

    o = slice(0, nocc)
    v = slice(nocc, nmo)

    ao2mo = AO2MOpyscf(C, verbose=mol.verbose, pyscfmol=mol)
    ao2mo.perform_rhf_partial()
    assert len(ao2mo.tei_mo) == ntransforms
    tei_mo_ovov_pyscf = ao2mo.tei_mo[0]
    tei_mo_oovv_pyscf = ao2mo.tei_mo[1]

    tei_ao = mol.intor("int2e_sph", aosym="s1")

    print("1. Use the class method explicitly.")

    tei_mo_ovov_hand = AO2MO.transform(
        tei_ao, C[0, :, o], C[0, :, v], C[0, :, o], C[0, :, v]
    )
    tei_mo_oovv_hand = AO2MO.transform(
        tei_ao, C[0, :, o], C[0, :, o], C[0, :, v], C[0, :, v]
    )

    assert tei_mo_ovov_pyscf.shape == tei_mo_ovov_hand.shape == (nocc, nvirt, nocc, nvirt)
    assert tei_mo_oovv_pyscf.shape == tei_mo_oovv_hand.shape == (nocc, nocc, nvirt, nvirt)
    np.testing.assert_allclose(tei_mo_ovov_hand, tei_mo_ovov_pyscf, rtol=0, atol=1.0e-15)
    np.testing.assert_allclose(tei_mo_oovv_hand, tei_mo_oovv_pyscf, rtol=0, atol=1.0e-15)

    print("2. Use the class method normally.")

    ao2mo_method = AO2MO(C, occupations, verbose=mol.verbose, I=tei_ao)
    ao2mo_method.perform_rhf_partial()
    assert len(ao2mo_method.tei_mo) == ntransforms
    tei_mo_ovov_method = ao2mo_method.tei_mo[0]
    tei_mo_oovv_method = ao2mo_method.tei_mo[1]

    assert (
        tei_mo_ovov_pyscf.shape == tei_mo_ovov_method.shape == (nocc, nvirt, nocc, nvirt)
    )
    assert (
        tei_mo_oovv_pyscf.shape == tei_mo_oovv_method.shape == (nocc, nocc, nvirt, nvirt)
    )
    np.testing.assert_allclose(
        tei_mo_ovov_method, tei_mo_ovov_pyscf, rtol=0, atol=1.0e-15
    )
    np.testing.assert_allclose(
        tei_mo_oovv_method, tei_mo_oovv_pyscf, rtol=0, atol=1.0e-15
    )

    return
示例#2
0
def test_electronicgtensor_small():

    mol = molecules.molecule_bc2h4_neutral_radical_sto3g()
    mol.build()

    mf = pyscf.scf.uhf.UHF(mol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = utils.occupations_from_pyscf_mol(mol, C)

    gtensor_calculator = magnetic.ElectronicGTensor(Program.PySCF, mol, C, E, occupations)
    gtensor_calculator.form_operators()
    gtensor_calculator.run(hamiltonian="rpa", spin="singlet")
    gtensor_calculator.form_results()

    print(ref_electronicgtensor_small)
    print(gtensor_calculator.g_oz_soc_1)

    assert np.all(
        np.equal(
            np.sign(ref_electronicgtensor_small), np.sign(gtensor_calculator.g_oz_soc_1)
        )
    )

    return
示例#3
0
    def form_rhs_geometric(
        self,
        C: np.ndarray,
        occupations: np.ndarray,
        natoms,
        MO_full,
        mints,
        return_dict: bool = False,
    ) -> None:
        from pyresponse.integrals import _form_rhs_geometric

        C_ = fix_mocoeffs_shape(C)
        B_dict = _form_rhs_geometric(C_[0], occupations, natoms, MO_full,
                                     mints)
        if return_dict:
            return B_dict
        # TODO I think this is wrong, because the matrices are [i, a]
        B_matrices = [B_dict[k].T for k in sorted(B_dict.keys())]
        B_vectors = [
            repack_matrix_to_vector(B)[:, np.newaxis] for B in B_matrices
        ]
        mo_integrals_ai_alph = np.stack(B_vectors)
        self.mo_integrals_ai_alph = mo_integrals_ai_alph
        # pylint: disable=invalid-unary-operand-type
        self.mo_integrals_ai_supervector_alph = np.concatenate(
            (mo_integrals_ai_alph, -mo_integrals_ai_alph), axis=1)
示例#4
0
def test_magnetizability_uhf() -> None:
    mol = molecules.molecule_glycine_sto3g()
    mol.charge = 1
    mol.spin = 1
    mol.build()

    mf = pyscf.scf.uhf.UHF(mol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = occupations_from_pyscf_mol(mol, C)

    calculator_common = magnetic.Magnetizability(
        Program.PySCF,
        mol,
        cphf.CPHF(solvers.ExactInv(C, E, occupations)),
        C,
        E,
        occupations,
    )
    calculator_common.form_operators()
    calculator_common.run(hamiltonian=Hamiltonian.RPA, spin=Spin.singlet)
    calculator_common.form_results()
    ref_eigvals, ref_iso, _ = utils.tensor_printer(ref_magnetizability_rohf)
    res_eigvals, res_iso, _ = utils.tensor_printer(
        calculator_common.magnetizability)
    thresh_eigval = 1.0e-1
    for i in range(3):
        assert abs(ref_eigvals[i] - res_eigvals[i]) < thresh_eigval
示例#5
0
def test_electronicgtensor_tiny() -> None:

    mol = molecules.molecule_lih_cation_sto3g()
    mol.build()

    mf = pyscf.scf.uhf.UHF(mol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = occupations_from_pyscf_mol(mol, C)

    gtensor_calculator = magnetic.ElectronicGTensor(
        Program.PySCF,
        mol,
        cphf.CPHF(solvers.ExactInv(C, E, occupations)),
        C,
        E,
        occupations,
    )
    gtensor_calculator.form_operators()
    gtensor_calculator.run(hamiltonian=Hamiltonian.RPA, spin=Spin.singlet)
    gtensor_calculator.form_results()

    print(ref_electronicgtensor_tiny)
    print(gtensor_calculator.g_oz_soc_1)

    assert np.all(
        np.equal(
            np.sign(ref_electronicgtensor_tiny),
            np.sign(utils.screen(gtensor_calculator.g_oz_soc_1)),
        ))
示例#6
0
def test_magnetizability_rhf():
    mol = molecules.molecule_glycine_sto3g()
    mol.build()

    mf = pyscf.scf.RHF(mol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = utils.occupations_from_pyscf_mol(mol, C)

    calculator_common = magnetic.Magnetizability(Program.PySCF, mol, C, E, occupations)
    calculator_common.form_operators()
    calculator_common.run(hamiltonian="rpa", spin="singlet")
    calculator_common.form_results()
    ref_eigvals, ref_iso, _ = utils.tensor_printer(ref_magnetizability_rhf)
    res_eigvals, res_iso, _ = utils.tensor_printer(calculator_common.magnetizability)
    thresh_eigval = 1.0e-3
    for i in range(3):
        assert abs(ref_eigvals[i] - res_eigvals[i]) < thresh_eigval

    # TODO it isn't so simple; there are actually many more terms
    # present when using London orbitals.
    # calculator_giao = magnetic.Magnetizability(mol, C, E, occupations, hamiltonian='rpa', spin='singlet', use_giao=True)
    # calculator_giao.form_operators()
    # calculator_giao.run()
    # calculator_giao.form_results()

    return
示例#7
0
def test_ORD_RPA_singlet_BC2H4_HF_STO3G():

    ref = BC2H4_HF_STO3G_RPA_singlet_nwchem

    pyscfmol = molecules.molecule_bc2h4_neutral_radical_sto3g()
    pyscfmol.build()

    mf = pyscf.scf.UHF(pyscfmol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = occupations_from_pyscf_mol(pyscfmol, C)

    frequencies = [0.0, 0.001, 0.0773178, 0.128347]
    ord_solver = optrot.ORD(
        Program.PySCF,
        pyscfmol,
        cphf.CPHF(solvers.ExactInv(C, E, occupations)),
        C,
        E,
        occupations,
        frequencies=frequencies,
        do_dipvel=False,
    )
    ord_solver.form_operators()
    ord_solver.run(hamiltonian=Hamiltonian.RPA, spin=Spin.singlet)
    ord_solver.form_results()

    print("Polarizabilities")
    assert len(frequencies) == len(ord_solver.polarizabilities)
    thresh = 6.5e-4
    for idxf, frequency in enumerate(frequencies):
        ref_polar = ref[frequency]["polar"]
        res_polar = ord_solver.polarizabilities[idxf]
        abs_diff = abs(res_polar - ref_polar)
        print(idxf, frequency)
        print(res_polar)
        print(abs_diff)
        if frequency == 0.128347:
            thresh = 6.0e-3
        assert (abs_diff < thresh).all()

    print(r"\beta(\omega)")
    thresh = 0.09
    for idxf, frequency in enumerate(frequencies):
        if "orbeta" in ref[frequency]:
            ref_beta = ref[frequency]["orbeta"]
            # TODO why no speed of light?
            # TODO why the (1/2)?
            res_beta = -(0.5 /
                         frequency) * ord_solver.driver.results[idxf][3:6, 0:3]
            abs_diff = abs(res_beta - ref_beta)
            print(idxf, frequency)
            print(res_beta)
            print(ref_beta)
            print(abs_diff)
            assert (abs_diff < thresh).all()
示例#8
0
def test_uncoupled_rhf() -> None:
    mol = molecules.molecule_trithiolane_sto3g()
    mol.build()

    mf = pyscf.scf.RHF(mol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = occupations_from_pyscf_mol(mol, C)

    solver = solvers.ExactInv(C, E, occupations)

    ao2mo = AO2MOpyscf(C, mol.verbose, mol)
    ao2mo.perform_rhf_partial()
    solver.tei_mo = ao2mo.tei_mo
    solver.tei_mo_type = AO2MOTransformationType.partial

    driver = cphf.CPHF(solver)

    operator_diplen = operators.Operator(label="dipole",
                                         is_imaginary=False,
                                         is_spin_dependent=False,
                                         triplet=False)
    integrals_diplen_ao = mol.intor("cint1e_r_sph", comp=3)
    operator_diplen.ao_integrals = integrals_diplen_ao
    driver.add_operator(operator_diplen)

    frequencies = [0.0, 0.0773178, 0.128347]
    driver.set_frequencies(frequencies)

    driver.run(
        hamiltonian=Hamiltonian.RPA,
        spin=Spin.singlet,
        program=Program.PySCF,
        program_obj=mol,
    )

    for idxf, frequency in enumerate(frequencies):
        print(idxf, frequency)
        print("uncoupled")
        diag_res = np.diag(driver.uncoupled_results[idxf])
        diag_ref = np.diag(rhf_uncoupled[frequency]["result"])
        diff = diag_res - diag_ref
        print(diag_res)
        print(diag_ref)
        print(diff)
        assert np.max(
            np.abs(diff)) < rhf_uncoupled[frequency]["error_max_diag"]
        print("coupled")
        diag_res = np.diag(driver.results[idxf])
        diag_ref = np.diag(rhf_coupled[frequency]["result"])
        diff = diag_res - diag_ref
        print(diag_res)
        print(diag_ref)
        print(diff)
        assert np.max(np.abs(diff)) < rhf_coupled[frequency]["error_max_diag"]
示例#9
0
def mocoeffs_from_psi4wfn(wfn: psi4.core.Wavefunction) -> np.ndarray:
    is_uhf = not wfn.same_a_b_orbs()
    Ca = wfn.Ca().to_array()
    if is_uhf:
        Cb = wfn.Cb().to_array()
        C = np.stack((Ca, Cb), axis=0)
    else:
        C = Ca
    # Clean up.
    return fix_mocoeffs_shape(C)
示例#10
0
    def __init__(self, C, occupations, verbose=1, I=None):

        self.C = fix_mocoeffs_shape(C)
        self.occupations = occupations
        self.verbose = verbose
        self.I = I

        self.nocc_alph, self.nvirt_alph, self.nocc_beta, self.nvirt_beta = occupations

        self.tei_mo = tuple()
示例#11
0
def test_iterators():
    """Test that each kind of iterator gives identical results."""

    mol = molecules_pyscf.molecule_glycine_sto3g()
    mol.charge = 1
    mol.spin = 1
    mol.build()

    mf = pyscf.scf.uhf.UHF(mol)
    mf.scf()

    assert isinstance(mf.mo_coeff, np.ndarray)
    assert len(mf.mo_coeff) == 2
    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = utils.occupations_from_pyscf_mol(mol, C)

    solver_ref = iterators.ExactInv(C, E, occupations)
    calculator_ref = magnetic.Magnetizability(Program.PySCF,
                                              mol,
                                              C,
                                              E,
                                              occupations,
                                              solver=solver_ref)
    calculator_ref.form_operators()
    calculator_ref.run(hamiltonian="rpa", spin="singlet")
    calculator_ref.form_results()

    ref = calculator_ref.magnetizability
    inv_funcs = (sp.linalg.inv, sp.linalg.pinv, sp.linalg.pinv2)

    thresh = 6.0e-14

    for inv_func in inv_funcs:
        solver_res = iterators.ExactInv(C, E, occupations, inv_func=inv_func)
        calculator_res = magnetic.Magnetizability(Program.PySCF,
                                                  mol,
                                                  C,
                                                  E,
                                                  occupations,
                                                  solver=solver_res)
        calculator_res.form_operators()
        calculator_res.run(hamiltonian="rpa", spin="singlet")
        calculator_res.form_results()

        np.testing.assert_equal(
            np.sign(calculator_ref.magnetizability),
            np.sign(calculator_res.magnetizability),
        )
        diff = calculator_ref.magnetizability - calculator_res.magnetizability
        abs_diff = np.abs(diff)
        print(abs_diff)
        assert np.all(abs_diff < thresh)

    return
示例#12
0
def test_uncoupled_uhf():
    mol = molecules.molecule_trithiolane_sto3g()
    mol.charge = 1
    mol.spin = 1
    mol.build()

    mf = pyscf.scf.uhf.UHF(mol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = utils.occupations_from_pyscf_mol(mol, C)

    solver = iterators.ExactInv(C, E, occupations)

    ao2mo = AO2MOpyscf(C, mol.verbose, mol)
    ao2mo.perform_uhf_partial()
    solver.tei_mo = ao2mo.tei_mo
    solver.tei_mo_type = "partial"

    driver = cphf.CPHF(solver)

    operator_diplen = operators.Operator(
        label="dipole", is_imaginary=False, is_spin_dependent=False, triplet=False
    )
    integrals_diplen_ao = mol.intor("cint1e_r_sph", comp=3)
    operator_diplen.ao_integrals = integrals_diplen_ao
    driver.add_operator(operator_diplen)

    frequencies = [0.0, 0.0773178, 0.128347, 0.4556355]
    driver.set_frequencies(frequencies)

    driver.run(solver_type="exact", hamiltonian="rpa", spin="singlet")

    for idxf, frequency in enumerate(frequencies):
        print(idxf, frequency)
        print("uncoupled")
        diag_res = np.diag(driver.uncoupled_results[idxf])
        diag_ref = np.diag(uhf_uncoupled[frequency]["result"])
        diff = diag_res - diag_ref
        print(diag_res)
        print(diag_ref)
        print(diff)
        assert np.max(np.abs(diff)) < uhf_uncoupled[frequency]["error_max_diag"]
        print("coupled")
        diag_res = np.diag(driver.results[idxf])
        diag_ref = np.diag(uhf_coupled[frequency]["result"])
        diff = diag_res - diag_ref
        print(diag_res)
        print(diag_ref)
        print(diff)
        assert np.max(np.abs(diff)) < uhf_coupled[frequency]["error_max_diag"]

    return
示例#13
0
    def __init__(
        self,
        C: np.ndarray,
        occupations: Sequence[int],
        verbose: int = 1,
        I: Optional[np.ndarray] = None,
    ) -> None:

        self.C = fix_mocoeffs_shape(C)
        self.occupations = occupations
        self.verbose = verbose
        self.I = I

        self.nocc_alph, self.nvirt_alph, self.nocc_beta, self.nvirt_beta = occupations

        self.tei_mo = tuple()
示例#14
0
def test_ORD_RPA_singlet_trithiolane_HF_STO3G():

    ref = trithiolane_HF_STO3G_RPA_singlet

    pyscfmol = molecules.molecule_trithiolane_sto3g()
    pyscfmol.build()

    mf = pyscf.scf.RHF(pyscfmol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = occupations_from_pyscf_mol(pyscfmol, C)

    frequencies = [0.0, 0.0773178, 0.128347]
    ord_solver = optrot.ORD(
        Program.PySCF,
        pyscfmol,
        cphf.CPHF(solvers.ExactInv(C, E, occupations)),
        C,
        E,
        occupations,
        frequencies=frequencies,
        do_dipvel=False,
    )
    ord_solver.form_operators()
    ord_solver.run(hamiltonian=Hamiltonian.RPA, spin=Spin.singlet)
    ord_solver.form_results()

    print("Polarizabilities")
    assert len(frequencies) == len(ord_solver.polarizabilities)
    thresh = 5.0e-4
    for idxf, frequency in enumerate(frequencies):
        ref_polar = ref[frequency]["polar"]
        res_polar = ord_solver.polarizabilities[idxf]
        abs_diff = abs(res_polar - ref_polar)
        print(idxf, frequency)
        print(res_polar)
        print(abs_diff)
        assert (abs_diff < thresh).all()
示例#15
0
def test_final_result_rhf_h2o_sto3g_rpa_singlet():
    hamiltonian = "rpa"
    spin = "singlet"

    C = utils.fix_mocoeffs_shape(utils.np_load(REFDIR / "C.npz"))
    E = utils.fix_moenergies_shape(utils.np_load(REFDIR / "F_MO.npz"))
    TEI_MO = utils.np_load(REFDIR / "TEI_MO.npz")
    # nocc_alph, nvirt_alph, nocc_beta, nvirt_beta
    occupations = [5, 2, 5, 2]
    stub = "h2o_sto3g_"
    dim = occupations[0] + occupations[1]
    mat_dipole_x = utils.parse_int_file_2(REFDIR / f"{stub}mux.dat", dim)
    mat_dipole_y = utils.parse_int_file_2(REFDIR / f"{stub}muy.dat", dim)
    mat_dipole_z = utils.parse_int_file_2(REFDIR / f"{stub}muz.dat", dim)

    solver = iterators.ExactInv(C, E, occupations)
    solver.tei_mo = (TEI_MO, )
    solver.tei_mo_type = "full"
    driver = cphf.CPHF(solver)
    ao_integrals_dipole = np.stack((mat_dipole_x, mat_dipole_y, mat_dipole_z),
                                   axis=0)
    operator_dipole = operators.Operator(label="dipole",
                                         is_imaginary=False,
                                         is_spin_dependent=False)
    operator_dipole.ao_integrals = ao_integrals_dipole
    driver.add_operator(operator_dipole)
    frequencies = (0.0, 0.02, 0.06, 0.1)
    driver.set_frequencies(frequencies)

    driver.run(solver_type="exact", hamiltonian=hamiltonian, spin=spin)

    assert len(driver.results) == len(frequencies)

    result__0_00 = np.array([[7.93556221, 0.0, 0.0], [0.0, 3.06821077, 0.0],
                             [0.0, 0.0, 0.05038621]])
    result__0_02 = np.array([[7.94312371, 0.0, 0.0], [0.0, 3.07051688, 0.0],
                             [0.0, 0.0, 0.05054685]])
    result__0_06 = np.array([[8.00414009, 0.0, 0.0], [0.0, 3.08913608, 0.0],
                             [0.0, 0.0, 0.05186977]])
    result__0_10 = np.array([[8.1290378, 0.0, 0.0], [0.0, 3.12731363, 0.0],
                             [0.0, 0.0, 0.05473482]])

    atol = 1.0e-8
    rtol = 0.0
    np.testing.assert_allclose(driver.results[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    # Reminder: there's no call to do SCF here because we already have
    # the MO coefficients.
    mol = molecules.molecule_water_sto3g()
    mol.build()
    polarizability = electric.Polarizability(Program.PySCF, mol, C, E,
                                             occupations, frequencies)
    polarizability.form_operators()
    polarizability.run(hamiltonian=hamiltonian, spin=spin)
    polarizability.form_results()

    np.testing.assert_allclose(polarizability.polarizabilities[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    return
示例#16
0
def test_HF_both_singlet_HF_STO3G():
    mol = pyscf.gto.Mole()
    mol.verbose = 0
    mol.output = None

    # pylint: disable=bad-whitespace
    mol.atom = [["H", (0.0, 0.0, 0.917)], ["F", (0.0, 0.0, 0.0)]]
    mol.basis = "sto-3g"
    mol.build()

    mf = pyscf.scf.RHF(mol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = utils.occupations_from_pyscf_mol(mol, C)
    solver_tda = iterators.ExactDiagonalizationSolverTDA(C, E, occupations)
    solver_tdhf = iterators.ExactDiagonalizationSolver(C, E, occupations)
    ao2mo = AO2MOpyscf(C, mol.verbose, mol)
    ao2mo.perform_rhf_partial()
    tei_mo = ao2mo.tei_mo
    solver_tda.tei_mo = tei_mo
    solver_tda.tei_mo_type = "partial"
    solver_tdhf.tei_mo = tei_mo
    solver_tdhf.tei_mo_type = "partial"
    driver_tda = td.TDA(solver_tda)
    driver_tdhf = td.TDHF(solver_tdhf)

    nroots = 5

    print("TDA using TDA()")
    driver_tda.run(solver_type="exact", hamiltonian="tda", spin="singlet")
    excitation_energies_tda_using_tda = driver_tda.solver.eigvals[:nroots].real
    print("TDA using TDHF()")
    driver_tdhf.run(solver_type="exact", hamiltonian="tda", spin="singlet")
    excitation_energies_tda_using_tdhf = driver_tdhf.solver.eigvals[:nroots].real
    print("RPA using TDHF()")
    driver_tdhf.run(solver_type="exact", hamiltonian="rpa", spin="singlet")
    excitation_energies_rpa = driver_tdhf.solver.eigvals[:nroots].real

    assert (
        excitation_energies_tda_using_tda.shape
        == excitation_energies_tda_using_tdhf.shape
    )
    assert excitation_energies_tda_using_tdhf.shape == excitation_energies_rpa.shape

    # There should be no difference in the TDA results regardless of
    # which implementation used.
    assert (
        excitation_energies_tda_using_tda - excitation_energies_tda_using_tdhf
    ).all() == 0

    # Now compare against reference_data
    ref_tda = HF_neutral_singlet_HF_STO3G_CIS_qchem
    ref_rpa = HF_neutral_singlet_HF_STO3G_RPA_qchem

    thresh = 1.0e-7
    for i in range(nroots):
        abs_diff = abs(ref_tda["etenergies"][i] - excitation_energies_tda_using_tda[i])
        assert abs_diff < thresh

    thresh = 1.0e-7
    for i in range(nroots):
        abs_diff = abs(ref_rpa["etenergies"][i] - excitation_energies_rpa[i])
        assert abs_diff < thresh

    return
示例#17
0
def occupations_from_pyscf_mol(mol: pyscf.gto.Mole, C: np.ndarray) -> np.ndarray:
    norb = fix_mocoeffs_shape(C).shape[-1]
    nocc_a, nocc_b = mol.nelec
    nvirt_a, nvirt_b = norb - nocc_a, norb - nocc_b
    return np.asarray([nocc_a, nvirt_a, nocc_b, nvirt_b], dtype=int)
示例#18
0
def test_ECD_RPA_singlet_BC2H4_cation_HF_STO3G() -> None:

    ref = BC2H4_cation_HF_STO3G_RPA_singlet_nwchem
    nroots = ref["nroots"]

    mol = molecules.molecule_bc2h4_cation_sto3g()
    mol.build()

    mf = pyscf.scf.RHF(mol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = occupations_from_pyscf_mol(mol, C)

    ecd_dipvel_rpa = ecd.ECD(
        Program.PySCF,
        mol,
        td.TDHF(solvers.ExactDiagonalizationSolver(C, E, occupations)),
        C,
        E,
        occupations,
        do_dipvel=True,
    )
    ecd_dipvel_rpa.form_operators()
    ecd_dipvel_rpa.run(hamiltonian=Hamiltonian.RPA, spin=Spin.singlet)
    ecd_dipvel_rpa.form_results()

    print("excitation energies")
    ref_etenergies = np.array(ref["etenergies"])
    res_etenergies = ecd_dipvel_rpa.driver.solver.eigvals.real[:nroots]
    print("ref, res")
    for refval, resval in zip(ref_etenergies, res_etenergies):
        print(refval, resval)
    thresh = 2.5e-7
    for i in range(nroots):
        abs_diff = abs(ref_etenergies[i] - res_etenergies[i])
        assert abs_diff < thresh

    print("dipole (length) oscillator strengths")
    ref_etoscslen = np.array(ref["etoscslen"])
    res_etoscslen = ecd_dipvel_rpa.driver.solver.operators[
        1].total_oscillator_strengths[:nroots]
    print("ref, res")
    for refval, resval in zip(ref_etoscslen, res_etoscslen):
        print(refval, resval)
    thresh = 1.0e-5
    for i in range(nroots):
        abs_diff = abs(ref_etoscslen[i] - res_etoscslen[i])
        assert abs_diff < thresh

    # TODO
    print("TODO dipole (mixed length/velocity) oscillator strengths")

    # TODO
    print("TODO dipole (velocity) oscillator strengths")
    ref_etoscsvel = np.array(ref["etoscsvel"])
    res_etoscsvel = ecd_dipvel_rpa.driver.solver.operators[
        2].total_oscillator_strengths[:nroots]
    # print('ref, res')
    # for refval, resval in zip(ref_etoscsvel, res_etoscsvel):
    #     print(refval, resval)
    # print(ref_etoscsvel / res_etoscsvel)
    # print(res_etoscsvel / ref_etoscsvel)

    print("rotatory strengths (length)")
    ref_etrotstrlen = np.array(ref["etrotstrlen"])
    res_etrotstrlen = ecd_dipvel_rpa.rotational_strengths_diplen[:nroots]
    print("ref, res")
    for refval, resval in zip(ref_etrotstrlen, res_etrotstrlen):
        print(refval, resval)
    # TODO unlike other quantities, the error isn't uniformly
    # distributed among the roots; how should this be handled?
    thresh = 1.5e1
    for i in range(nroots):
        abs_diff = abs(ref_etrotstrlen[i] - res_etrotstrlen[i])
        assert abs_diff < thresh

    print("rotatory strengths (velocity)")
    ref_etrotstrvel = np.array(ref["etrotstrvel"])
    res_etrotstrvel = ecd_dipvel_rpa.rotational_strengths_dipvel[:nroots]
    print("ref, res")
    for refval, resval in zip(ref_etrotstrvel, res_etrotstrvel):
        print(refval, resval)
    thresh = 1.0e-2
    for i in range(nroots):
        abs_diff = abs(ref_etrotstrvel[i] - res_etrotstrvel[i])
        assert abs_diff < thresh
示例#19
0
def test_first_hyperpolarizability_shg_rhf_wigner_explicit_psi4numpy_pyscf_large():
    mol = molecule_physicists_water_augccpvdz()
    mol.build()

    mf = pyscf.scf.RHF(mol)
    mf.kernel()
    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = occupations_from_pyscf_mol(mol, C)
    nocc_alph, nvirt_alph, _, _ = occupations
    nov_alph = nocc_alph * nvirt_alph
    norb = nocc_alph + nvirt_alph

    # calculate linear response vectors for electric dipole operator
    f1 = 0.0773178
    f2 = 2 * f1
    frequencies = [f1, f2]
    calculator = electric.Polarizability(
        Program.PySCF,
        mol,
        cphf.CPHF(solvers.ExactInv(C, E, occupations)),
        C,
        E,
        occupations,
        frequencies=frequencies,
    )
    calculator.form_operators()
    calculator.run(hamiltonian=Hamiltonian.RPA, spin=Spin.singlet)
    calculator.form_results()

    polarizability_1 = calculator.polarizabilities[0]
    polarizability_2 = calculator.polarizabilities[1]
    print("polarizability: {} a.u.".format(f1))
    print(polarizability_1)
    print("polarizability: {} a.u. (frequency doubled)".format(f2))
    print(polarizability_2)

    # each operator contains multiple sets of response vectors, one
    # set of components for each frequency
    assert isinstance(calculator.driver.solver.operators, list)
    assert len(calculator.driver.solver.operators) == 1
    operator = calculator.driver.solver.operators[0]
    rhsvecs = operator.mo_integrals_ai_supervector_alph
    assert isinstance(operator.rspvecs_alph, list)
    assert len(operator.rspvecs_alph) == 2
    rspvecs_1 = operator.rspvecs_alph[0]
    rspvecs_2 = operator.rspvecs_alph[1]

    ## Form the full [norb, norb] representation of everything.
    # Response vectors: transform X_{ia} and Y_{ia} -> U_{p,q}
    # 0. 'a' is fast index, 'i' slow
    # 1. rspvec == [X Y]
    # 2. U_{p, q} -> zero
    # 3. place X_{ia} into U_{i, a}
    # 4. place Y_{ia} into U_{a, i}

    ncomp = rhsvecs.shape[0]

    rspmats_1 = np.zeros(shape=(ncomp, norb, norb))
    rspmats_2 = np.zeros(shape=(ncomp, norb, norb))
    for i in range(ncomp):
        rspvec_1 = rspvecs_1[i, :, 0]
        rspvec_2 = rspvecs_2[i, :, 0]
        x_1 = rspvec_1[:nov_alph]
        y_1 = rspvec_1[nov_alph:]
        x_2 = rspvec_2[:nov_alph]
        y_2 = rspvec_2[nov_alph:]
        x_full_1 = utils.repack_vector_to_matrix(x_1, (nvirt_alph, nocc_alph))
        y_full_1 = utils.repack_vector_to_matrix(y_1, (nvirt_alph, nocc_alph))
        x_full_2 = utils.repack_vector_to_matrix(x_2, (nvirt_alph, nocc_alph))
        y_full_2 = utils.repack_vector_to_matrix(y_2, (nvirt_alph, nocc_alph))
        rspmats_1[i, :nocc_alph, nocc_alph:] = y_full_1.T
        rspmats_1[i, nocc_alph:, :nocc_alph] = x_full_1
        rspmats_2[i, :nocc_alph, nocc_alph:] = y_full_2.T
        rspmats_2[i, nocc_alph:, :nocc_alph] = x_full_2

    rhsmats = np.zeros(shape=(ncomp, norb, norb))
    for i in range(ncomp):
        rhsvec = rhsvecs[i, :, 0]
        rhsvec_top = rhsvec[:nov_alph]
        rhsvec_bot = rhsvec[nov_alph:]
        rhsvec_top_mat = utils.repack_vector_to_matrix(rhsvec_top, (nvirt_alph, nocc_alph))
        rhsvec_bot_mat = utils.repack_vector_to_matrix(rhsvec_bot, (nvirt_alph, nocc_alph))
        rhsmats[i, :nocc_alph, nocc_alph:] = rhsvec_top_mat.T
        rhsmats[i, nocc_alph:, :nocc_alph] = rhsvec_bot_mat

    polarizability_full_1 = np.empty_like(polarizability_1)
    polarizability_full_2 = np.empty_like(polarizability_2)
    for a in (0, 1, 2):
        for b in (0, 1, 2):
            polarizability_full_1[a, b] = 2 * np.trace(np.dot(rhsmats[a].T, rspmats_1[b]))
            polarizability_full_2[a, b] = 2 * np.trace(np.dot(rhsmats[a].T, rspmats_2[b]))

    np.testing.assert_almost_equal(polarizability_1, -polarizability_full_1)
    np.testing.assert_almost_equal(polarizability_2, -polarizability_full_2)

    # V_{p,q} <- full MO transformation of right hand side
    integrals_ao = operator.ao_integrals
    integrals_mo = np.empty_like(integrals_ao)
    for i in range(ncomp):
        integrals_mo[i] = (C[0].T).dot(integrals_ao[i]).dot(C[0])

    G_1 = np.empty_like(rspmats_1)
    G_2 = np.empty_like(rspmats_2)
    C = mf.mo_coeff
    # TODO I feel as though if I have all the MO-basis two-electron
    # integrals, I shouldn't need another JK build.
    for i in range(ncomp):
        V = integrals_mo[i]
        Dl_1 = (C[:, :nocc_alph]).dot(rspmats_1[i, :nocc_alph, :]).dot(C.T)
        Dr_1 = (-C).dot(rspmats_1[i, :, :nocc_alph]).dot(C[:, :nocc_alph].T)
        D_1 = Dl_1 + Dr_1
        Dl_2 = (C[:, :nocc_alph]).dot(rspmats_2[i, :nocc_alph, :]).dot(C.T)
        Dr_2 = (-C).dot(rspmats_2[i, :, :nocc_alph]).dot(C[:, :nocc_alph].T)
        D_2 = Dl_2 + Dr_2
        J_1, K_1 = mf.get_jk(mol, D_1, hermi=0)
        J_2, K_2 = mf.get_jk(mol, D_2, hermi=0)
        F_AO_1 = 2 * J_1 - K_1
        F_AO_2 = 2 * J_2 - K_2
        F_MO_1 = (C.T).dot(F_AO_1).dot(C)
        F_MO_2 = (C.T).dot(F_AO_2).dot(C)
        G_1[i] = V + F_MO_1
        G_2[i] = V + F_MO_2

    E_diag = np.diag(E[0, ...])
    epsilon_1 = G_1.copy()
    epsilon_2 = G_2.copy()
    for i in range(ncomp):
        eoU_1 = (E_diag[..., np.newaxis] + f1) * rspmats_1[i]
        Ue_1 = rspmats_1[i] * E_diag[np.newaxis, ...]
        epsilon_1[i] += eoU_1 - Ue_1
        eoU_2 = (E_diag[..., np.newaxis] + f2) * rspmats_2[i]
        Ue_2 = rspmats_2[i] * E_diag[np.newaxis, ...]
        epsilon_2[i] += eoU_2 - Ue_2

    # Assume some symmetry and calculate only part of the tensor.

    hyperpolarizability = np.zeros(shape=(6, 3))
    off1 = [0, 1, 2, 0, 0, 1]
    off2 = [0, 1, 2, 1, 2, 2]
    for r in range(6):
        b = off1[r]
        c = off2[r]
        for a in range(3):
            tl1 = np.trace(rspmats_2[a].T.dot(G_1[b]).dot(rspmats_1[c])[:nocc_alph, :nocc_alph])
            tl2 = np.trace(rspmats_1[c].dot(G_1[b]).dot(rspmats_2[a].T)[:nocc_alph, :nocc_alph])
            tl3 = np.trace(rspmats_2[a].T.dot(G_1[c]).dot(rspmats_1[b])[:nocc_alph, :nocc_alph])
            tl4 = np.trace(rspmats_1[b].dot(G_1[c]).dot(rspmats_2[a].T)[:nocc_alph, :nocc_alph])
            tl5 = np.trace(rspmats_1[c].dot(-G_2[a].T).dot(rspmats_1[b])[:nocc_alph, :nocc_alph])
            tl6 = np.trace(rspmats_1[b].dot(-G_2[a].T).dot(rspmats_1[c])[:nocc_alph, :nocc_alph])
            tr1 = np.trace(
                rspmats_1[c].dot(rspmats_1[b]).dot(-epsilon_2[a].T)[:nocc_alph, :nocc_alph]
            )
            tr2 = np.trace(
                rspmats_1[b].dot(rspmats_1[c]).dot(-epsilon_2[a].T)[:nocc_alph, :nocc_alph]
            )
            tr3 = np.trace(
                rspmats_1[c].dot(rspmats_2[a].T).dot(epsilon_1[b])[:nocc_alph, :nocc_alph]
            )
            tr4 = np.trace(
                rspmats_2[a].T.dot(rspmats_1[c]).dot(epsilon_1[b])[:nocc_alph, :nocc_alph]
            )
            tr5 = np.trace(
                rspmats_1[b].dot(rspmats_2[a].T).dot(epsilon_1[c])[:nocc_alph, :nocc_alph]
            )
            tr6 = np.trace(
                rspmats_2[a].T.dot(rspmats_1[b]).dot(epsilon_1[c])[:nocc_alph, :nocc_alph]
            )
            tl = tl1 + tl2 + tl3 + tl4 + tl5 + tl6
            tr = tr1 + tr2 + tr3 + tr4 + tr5 + tr6
            hyperpolarizability[r, a] = -2 * (tl - tr)

    # pylint: disable=C0326
    ref = np.array(
        [
            [0.00000000, 0.00000000, 1.92505358],
            [0.00000000, 0.00000000, -31.33652886],
            [0.00000000, 0.00000000, -13.92830863],
            [0.00000000, 0.00000000, 0.00000000],
            [-1.80626084, 0.00000000, 0.00000000],
            [0.00000000, -31.13504192, 0.00000000],
        ]
    )
    ref_avgs = np.array([0.00000000, 0.00000000, 45.69300223])
    ref_avg = 45.69300223
    diff = np.abs(ref - hyperpolarizability)
    print("abs diff")
    print(diff)
    thresh = 2.5e-04
    assert np.all(diff < thresh)

    print("hyperpolarizability: SHG, (-{}; {}, {}), symmetry-unique components".format(f2, f1, f1))
    print(hyperpolarizability)
    print("ref")
    print(ref)

    # Transpose all frequency-doubled quantities (+2w) to get -2w.

    for i in range(ncomp):
        rspmats_2[i] = rspmats_2[i].T
        G_2[i] = -G_2[i].T
        epsilon_2[i] = -epsilon_2[i].T

    # Assume some symmetry and calculate only part of the tensor. This
    # time, work with the in-place manipulated quantities (this tests
    # their correctness).

    mU = (rspmats_2, rspmats_1)
    mG = (G_2, G_1)
    me = (epsilon_2, epsilon_1)

    hyperpolarizability = np.zeros(shape=(6, 3))
    off1 = [0, 1, 2, 0, 0, 1]
    off2 = [0, 1, 2, 1, 2, 2]
    for r in range(6):
        b = off1[r]
        c = off2[r]
        for a in range(3):
            tl1 = np.trace(mU[0][a].dot(mG[1][b]).dot(mU[1][c])[:nocc_alph, :nocc_alph])
            tl2 = np.trace(mU[1][c].dot(mG[1][b]).dot(mU[0][a])[:nocc_alph, :nocc_alph])
            tl3 = np.trace(mU[0][a].dot(mG[1][c]).dot(mU[1][b])[:nocc_alph, :nocc_alph])
            tl4 = np.trace(mU[1][b].dot(mG[1][c]).dot(mU[0][a])[:nocc_alph, :nocc_alph])
            tl5 = np.trace(mU[1][c].dot(mG[0][a]).dot(mU[1][b])[:nocc_alph, :nocc_alph])
            tl6 = np.trace(mU[1][b].dot(mG[0][a]).dot(mU[1][c])[:nocc_alph, :nocc_alph])
            tr1 = np.trace(mU[1][c].dot(mU[1][b]).dot(me[0][a])[:nocc_alph, :nocc_alph])
            tr2 = np.trace(mU[1][b].dot(mU[1][c]).dot(me[0][a])[:nocc_alph, :nocc_alph])
            tr3 = np.trace(mU[1][c].dot(mU[0][a]).dot(me[1][b])[:nocc_alph, :nocc_alph])
            tr4 = np.trace(mU[0][a].dot(mU[1][c]).dot(me[1][b])[:nocc_alph, :nocc_alph])
            tr5 = np.trace(mU[1][b].dot(mU[0][a]).dot(me[1][c])[:nocc_alph, :nocc_alph])
            tr6 = np.trace(mU[0][a].dot(mU[1][b]).dot(me[1][c])[:nocc_alph, :nocc_alph])
            tl = [tl1, tl2, tl3, tl4, tl5, tl6]
            tr = [tr1, tr2, tr3, tr4, tr5, tr6]
            hyperpolarizability[r, a] = -2 * (sum(tl) - sum(tr))

    assert np.all(np.abs(ref - hyperpolarizability) < thresh)

    # Assume no symmetry and calculate the full tensor.

    hyperpolarizability_full = np.zeros(shape=(3, 3, 3))

    # components x, y, z
    for ip, p in enumerate(list(product(range(3), range(3), range(3)))):
        a, b, c = p
        tl, tr = [], []
        # 1st tuple -> index a, b, c (*not* x, y, z!)
        # 2nd tuple -> index frequency (0 -> -2w, 1 -> +w)
        for iq, q in enumerate(list(permutations(zip(p, (0, 1, 1)), 3))):
            d, e, f = q
            tlp = (mU[d[1]][d[0]]).dot(mG[e[1]][e[0]]).dot(mU[f[1]][f[0]])
            tle = np.trace(tlp[:nocc_alph, :nocc_alph])
            tl.append(tle)
            trp = (mU[d[1]][d[0]]).dot(mU[e[1]][e[0]]).dot(me[f[1]][f[0]])
            tre = np.trace(trp[:nocc_alph, :nocc_alph])
            tr.append(tre)
        hyperpolarizability_full[a, b, c] = -2 * (sum(tl) - sum(tr))
    print("hyperpolarizability: SHG, (-{}; {}, {}), full tensor".format(f2, f1, f1))
    print(hyperpolarizability_full)

    # Check that the elements of the reduced and full tensors are
    # equivalent.

    for r in range(6):
        b = off1[r]
        c = off2[r]
        for a in range(3):
            diff = hyperpolarizability[r, a] - hyperpolarizability_full[a, b, c]
            # TODO why not 14?
            assert abs(diff) < 1.0e-13

    # Compute averages and compare to reference.

    avgs, avg = utils.form_first_hyperpolarizability_averages(hyperpolarizability_full)
    assert np.allclose(ref_avgs, avgs, rtol=0, atol=1.0e-3)
    assert np.allclose([ref_avg], [avg], rtol=0, atol=1.0e-3)
    print(avgs)
    print(avg)

    return
示例#20
0
def test_final_result_rhf_h2o_sto3g_rpa_singlet() -> None:
    """Test correctness of the final result for water/STO-3G with full RPA for
    singlet response induced by the dipole length operator (the electric
    polarizability) computed with quantities from disk.
    """
    hamiltonian = Hamiltonian.RPA
    spin = Spin.singlet

    C = utils.fix_mocoeffs_shape(utils.np_load(REFDIR / "C.npz"))
    E = utils.fix_moenergies_shape(utils.np_load(REFDIR / "F_MO.npz"))
    TEI_MO = utils.np_load(REFDIR / "TEI_MO.npz")
    # nocc_alph, nvirt_alph, nocc_beta, nvirt_beta
    occupations = np.asarray([5, 2, 5, 2], dtype=int)
    stub = "h2o_sto3g_"
    dim = occupations[0] + occupations[1]
    mat_dipole_x = utils.parse_int_file_2(REFDIR / f"{stub}mux.dat", dim)
    mat_dipole_y = utils.parse_int_file_2(REFDIR / f"{stub}muy.dat", dim)
    mat_dipole_z = utils.parse_int_file_2(REFDIR / f"{stub}muz.dat", dim)

    solver = solvers.ExactInv(C, E, occupations)
    solver.tei_mo = (TEI_MO, )
    solver.tei_mo_type = AO2MOTransformationType.full
    driver = cphf.CPHF(solver)
    ao_integrals_dipole = np.stack((mat_dipole_x, mat_dipole_y, mat_dipole_z),
                                   axis=0)
    operator_dipole = operators.Operator(label="dipole",
                                         is_imaginary=False,
                                         is_spin_dependent=False)
    operator_dipole.ao_integrals = ao_integrals_dipole
    driver.add_operator(operator_dipole)
    frequencies = (0.0, 0.02, 0.06, 0.1)
    driver.set_frequencies(frequencies)

    driver.run(hamiltonian=hamiltonian,
               spin=spin,
               program=None,
               program_obj=None)

    assert len(driver.results) == len(frequencies)

    result__0_00 = np.array([[7.93556221, 0.0, 0.0], [0.0, 3.06821077, 0.0],
                             [0.0, 0.0, 0.05038621]])
    result__0_02 = np.array([[7.94312371, 0.0, 0.0], [0.0, 3.07051688, 0.0],
                             [0.0, 0.0, 0.05054685]])
    result__0_06 = np.array([[8.00414009, 0.0, 0.0], [0.0, 3.08913608, 0.0],
                             [0.0, 0.0, 0.05186977]])
    result__0_10 = np.array([[8.1290378, 0.0, 0.0], [0.0, 3.12731363, 0.0],
                             [0.0, 0.0, 0.05473482]])

    atol = 1.0e-8
    rtol = 0.0
    np.testing.assert_allclose(driver.results[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    # Reminder: there's no call to do SCF here because we already have
    # the MO coefficients.
    mol = molecules.molecule_water_sto3g()
    mol.build()
    polarizability = electric.Polarizability(
        Program.PySCF,
        mol,
        cphf.CPHF(solvers.ExactInv(C, E, occupations)),
        C,
        E,
        occupations,
        frequencies=frequencies,
    )
    polarizability.form_operators()
    polarizability.run(hamiltonian=hamiltonian, spin=spin)
    polarizability.form_results()

    np.testing.assert_allclose(polarizability.polarizabilities[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)
示例#21
0
def test_final_result_rhf_h2o_sto3g_tda_triplet() -> None:
    """Test correctness of the final result for water/STO-3G with the TDA
    approximation/CIS for triplet response induced by the dipole length
    operator computed with quantities from disk.
    """
    hamiltonian = Hamiltonian.TDA
    spin = Spin.triplet

    C = utils.fix_mocoeffs_shape(utils.np_load(REFDIR / "C.npz"))
    E = utils.fix_moenergies_shape(utils.np_load(REFDIR / "F_MO.npz"))
    TEI_MO = utils.np_load(REFDIR / "TEI_MO.npz")
    # nocc_alph, nvirt_alph, nocc_beta, nvirt_beta
    occupations = np.asarray([5, 2, 5, 2], dtype=int)
    stub = "h2o_sto3g_"
    dim = occupations[0] + occupations[1]
    mat_dipole_x = utils.parse_int_file_2(REFDIR / f"{stub}mux.dat", dim)
    mat_dipole_y = utils.parse_int_file_2(REFDIR / f"{stub}muy.dat", dim)
    mat_dipole_z = utils.parse_int_file_2(REFDIR / f"{stub}muz.dat", dim)

    solver = solvers.ExactInv(C, E, occupations)
    solver.tei_mo = (TEI_MO, )
    solver.tei_mo_type = AO2MOTransformationType.full
    driver = cphf.CPHF(solver)
    ao_integrals_dipole = np.stack((mat_dipole_x, mat_dipole_y, mat_dipole_z),
                                   axis=0)
    operator_dipole = operators.Operator(label="dipole",
                                         is_imaginary=False,
                                         is_spin_dependent=False)
    operator_dipole.ao_integrals = ao_integrals_dipole
    driver.add_operator(operator_dipole)
    frequencies = (0.0, 0.02, 0.06, 0.1)
    driver.set_frequencies(frequencies)

    driver.run(hamiltonian=hamiltonian,
               spin=spin,
               program=None,
               program_obj=None)

    assert len(driver.results) == len(frequencies)

    result__0_00 = np.array([[14.64430714, 0.0, 0.0], [0.0, 8.80921432, 0.0],
                             [0.0, 0.0, 0.06859496]])
    result__0_02 = np.array([[14.68168443, 0.0, 0.0], [0.0, 8.83562647, 0.0],
                             [0.0, 0.0, 0.0689291]])
    result__0_06 = np.array([[14.98774296, 0.0, 0.0], [0.0, 9.0532224, 0.0],
                             [0.0, 0.0, 0.07172414]])
    result__0_10 = np.array([[15.63997724, 0.0, 0.0], [0.0, 9.52504267, 0.0],
                             [0.0, 0.0, 0.07805428]])

    atol = 1.0e-8
    rtol = 0.0
    np.testing.assert_allclose(driver.results[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    mol = molecules.molecule_water_sto3g()
    mol.build()
    polarizability = electric.Polarizability(
        Program.PySCF,
        mol,
        cphf.CPHF(solvers.ExactInv(C, E, occupations)),
        C,
        E,
        occupations,
        frequencies=frequencies,
    )
    polarizability.form_operators()
    polarizability.run(hamiltonian=hamiltonian, spin=spin)
    polarizability.form_results()

    np.testing.assert_allclose(polarizability.polarizabilities[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)
示例#22
0
def test_first_hyperpolarizability_static_rhf_wigner_explicit():
    mol = molecule_water_sto3g_angstrom()
    mol.build()

    mf = pyscf.scf.RHF(mol)
    mf.kernel()
    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = utils.occupations_from_pyscf_mol(mol, C)
    nocc_alph, nvirt_alph, _, _ = occupations
    nov_alph = nocc_alph * nvirt_alph
    norb = nocc_alph + nvirt_alph

    # calculate linear response vectors for electric dipole operator
    calculator = electric.Polarizability(Program.PySCF,
                                         mol,
                                         C,
                                         E,
                                         occupations,
                                         frequencies=[0.0])
    calculator.form_operators()
    calculator.run()
    calculator.form_results()

    polarizability = calculator.polarizabilities[0]
    print("polarizability (static)")
    print(polarizability)

    operator = calculator.driver.solver.operators[0]
    rhsvecs = operator.mo_integrals_ai_supervector_alph
    rspvecs = operator.rspvecs_alph[0]

    ## Form the full [norb, norb] representation of everything.
    # Response vectors: transform X_{ia} and Y_{ia} -> U_{p,q}
    # 0. 'a' is fast index, 'i' slow
    # 1. rspvec == [X Y]
    # 2. U_{p, q} -> zero
    # 3. place X_{ia} into U_{i, a}
    # 4. place Y_{ia} into U_{a, i}

    ncomp = rhsvecs.shape[0]

    rspmats = np.zeros(shape=(ncomp, norb, norb))
    for i in range(ncomp):
        rspvec = rspvecs[i, :, 0]
        x = rspvec[:nov_alph]
        y = rspvec[nov_alph:]
        x_full = utils.repack_vector_to_matrix(x, (nvirt_alph, nocc_alph))
        y_full = utils.repack_vector_to_matrix(y, (nvirt_alph, nocc_alph))
        rspmats[i, :nocc_alph, nocc_alph:] = x_full.T
        rspmats[i, nocc_alph:, :nocc_alph] = y_full

    rhsmats = np.zeros(shape=(ncomp, norb, norb))
    for i in range(ncomp):
        rhsvec = rhsvecs[i, :, 0]
        rhsvec_top = rhsvec[:nov_alph]
        rhsvec_bot = rhsvec[nov_alph:]
        rhsvec_top_mat = utils.repack_vector_to_matrix(rhsvec_top,
                                                       (nvirt_alph, nocc_alph))
        rhsvec_bot_mat = utils.repack_vector_to_matrix(rhsvec_bot,
                                                       (nvirt_alph, nocc_alph))
        rhsmats[i, :nocc_alph, nocc_alph:] = rhsvec_top_mat.T
        rhsmats[i, nocc_alph:, :nocc_alph] = rhsvec_bot_mat

    polarizability_full = np.empty_like(polarizability)
    for a in (0, 1, 2):
        for b in (0, 1, 2):
            polarizability_full[a, b] = 2 * np.trace(rhsmats[a, ...].T.dot(
                rspmats[b, ...]))

    np.testing.assert_almost_equal(polarizability, polarizability_full)

    # V_{p,q} <- full MO transformation of right hand side
    integrals_ao = operator.ao_integrals
    integrals_mo = np.empty_like(integrals_ao)
    for i in range(ncomp):
        integrals_mo[i, ...] = (C[0, ...].T).dot(integrals_ao[i,
                                                              ...]).dot(C[0,
                                                                          ...])

    G = np.empty_like(rspmats)
    C = mf.mo_coeff
    # TODO I feel as though if I have all the MO-basis two-electron
    # integrals, I shouldn't need another JK build.
    for i in range(ncomp):
        V = integrals_mo[i, ...]
        Dl = (C[:, nocc_alph:].dot(
            utils.repack_vector_to_matrix(rspvecs[i, :nov_alph, 0],
                                          (nvirt_alph, nocc_alph))).dot(
                                              C[:, :nocc_alph].T))
        J, K = mf.get_jk(mol, Dl, hermi=0)
        F_AO = -(4 * J - K - K.T)
        F_MO = (C.T).dot(F_AO).dot(C)
        G[i, ...] = V + F_MO

    E_diag = np.diag(E[0, ...])
    epsilon = G.copy()
    omega = 0
    for i in range(ncomp):
        eoU = (E_diag[..., np.newaxis] + omega) * rspmats[i, ...]
        Ue = rspmats[i, ...] * E_diag[np.newaxis, ...]
        epsilon[i, ...] += eoU - Ue

    # Assume some symmetry and calculate only part of the tensor.

    hyperpolarizability = np.zeros(shape=(6, 3))
    off1 = [0, 1, 2, 0, 0, 1]
    off2 = [0, 1, 2, 1, 2, 2]
    for r in range(6):
        b = off1[r]
        c = off2[r]
        for a in range(3):
            tl1 = 2 * np.trace(rspmats[a, ...].dot(G[b, ...]).dot(
                rspmats[c, ...])[:nocc_alph, :nocc_alph])
            tl2 = 2 * np.trace(rspmats[a, ...].dot(G[c, ...]).dot(
                rspmats[b, ...])[:nocc_alph, :nocc_alph])
            tl3 = 2 * np.trace(rspmats[c, ...].dot(G[a, ...]).dot(
                rspmats[b, ...])[:nocc_alph, :nocc_alph])
            tr1 = np.trace(rspmats[c, ...].dot(rspmats[b, ...]).dot(
                epsilon[a, ...])[:nocc_alph, :nocc_alph])
            tr2 = np.trace(rspmats[b, ...].dot(rspmats[c, ...]).dot(
                epsilon[a, ...])[:nocc_alph, :nocc_alph])
            tr3 = np.trace(rspmats[c, ...].dot(rspmats[a, ...]).dot(
                epsilon[b, ...])[:nocc_alph, :nocc_alph])
            tr4 = np.trace(rspmats[a, ...].dot(rspmats[c, ...]).dot(
                epsilon[b, ...])[:nocc_alph, :nocc_alph])
            tr5 = np.trace(rspmats[b, ...].dot(rspmats[a, ...]).dot(
                epsilon[c, ...])[:nocc_alph, :nocc_alph])
            tr6 = np.trace(rspmats[a, ...].dot(rspmats[b, ...]).dot(
                epsilon[c, ...])[:nocc_alph, :nocc_alph])
            tl = tl1 + tl2 + tl3
            tr = tr1 + tr2 + tr3 + tr4 + tr5 + tr6
            hyperpolarizability[r, a] = 2 * (tl - tr)

    # pylint: disable=C0326
    ref = np.array([
        [-8.86822254, 0.90192130, -0.50796586],
        [1.98744058, 5.13635628, -2.95319400],
        [0.66008119, 1.62699646, -0.85632412],
        [0.90192130, 1.98744058, -1.09505123],
        [-0.50796586, -1.09505123, 0.66008119],
        [-1.09505123, -2.95319400, 1.62699646],
    ])
    ref_avgs = np.array([6.22070078, -7.66527404, 4.31748398])
    ref_avg = 10.77470242

    thresh = 1.5e-4
    assert np.all(np.abs(ref - hyperpolarizability) < thresh)

    print("hyperpolarizability (static), symmetry-unique components")
    print(hyperpolarizability)

    # Assume no symmetry and calculate the full tensor.

    hyperpolarizability_full = np.zeros(shape=(3, 3, 3))
    for p in product(range(3), range(3), range(3)):
        a, b, c = p
        tl, tr = 0, 0
        for q in permutations(p, 3):
            d, e, f = q
            tl += np.trace(rspmats[d, ...].dot(G[e, ...]).dot(
                rspmats[f, ...])[:nocc_alph, :nocc_alph])
            tr += np.trace(rspmats[d, ...].dot(rspmats[e, ...]).dot(
                epsilon[f, ...])[:nocc_alph, :nocc_alph])
        hyperpolarizability_full[a, b, c] = 2 * (tl - tr)
    print("hyperpolarizability (static), full tensor")
    print(hyperpolarizability_full)

    # Check that the elements of the reduced and full tensors are
    # equivalent.

    thresh = 1.0e-14
    for r in range(6):
        b = off1[r]
        c = off2[r]
        for a in range(3):
            diff = hyperpolarizability[r, a] - hyperpolarizability_full[a, b,
                                                                        c]
            assert abs(diff) < thresh

    # Compute averages and compare to reference.
    # This is the slow way.
    # avgs = []
    # for i in range(3):
    #     avg_c = 0
    #     for j in range(3):
    #         avg_c += hyperpolarizability_full[i, j, j] + hyperpolarizability_full[j, i, j] + hyperpolarizability_full[j, j, i]
    #     avgs.append((-1/3) * avg_c)
    # print(np.asarray(avgs))
    x = hyperpolarizability_full
    # This is the simplest non-einsum way.
    # avgs = (-1 / 3) * np.asarray([np.trace(x[i, :, :] + x[:, i, :] + x[:, :, i]) for i in range(3)])
    # This is the best way.
    avgs = (-1 / 3) * (np.einsum("ijj->i", x) + np.einsum("jij->i", x) +
                       np.einsum("jji->i", x))
    # print(list(set([''.join(p) for p in list(permutations('ijj', 3))])))
    assert np.allclose(ref_avgs, avgs, rtol=0, atol=1.0e-3)
    avg = np.sum(avgs**2)**(1 / 2)
    assert np.allclose([ref_avg], [avg], rtol=0, atol=1.0e-3)
    print(avgs)
    print(avg)

    utils_avgs, utils_avg = utils.form_first_hyperpolarizability_averages(x)
    assert np.allclose(avgs, utils_avgs, rtol=0, atol=1.0e-13)
    assert np.allclose([avg], [utils_avg], rtol=0, atol=1.0e-13)

    return
示例#23
0
def test_final_result_rhf_h2o_sto3g_rpa_triplet() -> None:
    """Test correctness of the final result for water/STO-3G with full RPA for
    triplet response induced by the dipole length operator computed with
    quantities from disk.
    """
    hamiltonian = Hamiltonian.RPA
    spin = Spin.triplet

    C = utils.fix_mocoeffs_shape(utils.np_load(REFDIR / "C.npz"))
    E = utils.fix_moenergies_shape(utils.np_load(REFDIR / "F_MO.npz"))
    TEI_MO = utils.np_load(REFDIR / "TEI_MO.npz")
    # nocc_alph, nvirt_alph, nocc_beta, nvirt_beta
    occupations = np.asarray([5, 2, 5, 2], dtype=int)
    stub = "h2o_sto3g_"
    dim = occupations[0] + occupations[1]
    mat_dipole_x = utils.parse_int_file_2(REFDIR / f"{stub}mux.dat", dim)
    mat_dipole_y = utils.parse_int_file_2(REFDIR / f"{stub}muy.dat", dim)
    mat_dipole_z = utils.parse_int_file_2(REFDIR / f"{stub}muz.dat", dim)

    solver = solvers.ExactInv(C, E, occupations)
    solver.tei_mo = (TEI_MO, )
    solver.tei_mo_type = AO2MOTransformationType.full
    driver = cphf.CPHF(solver)
    ao_integrals_dipole = np.stack((mat_dipole_x, mat_dipole_y, mat_dipole_z),
                                   axis=0)
    operator_dipole = operators.Operator(label="dipole",
                                         is_imaginary=False,
                                         is_spin_dependent=False)
    operator_dipole.ao_integrals = ao_integrals_dipole
    driver.add_operator(operator_dipole)
    frequencies = (0.0, 0.02, 0.06, 0.1)
    driver.set_frequencies(frequencies)

    driver.run(hamiltonian=hamiltonian,
               spin=spin,
               program=None,
               program_obj=None)

    assert len(driver.results) == len(frequencies)

    result__0_00 = np.array([[26.59744305, 0.0, 0.0], [0.0, 18.11879557, 0.0],
                             [0.0, 0.0, 0.07798969]])
    result__0_02 = np.array([[26.68282287, 0.0, 0.0], [0.0, 18.19390051, 0.0],
                             [0.0, 0.0, 0.07837521]])
    result__0_06 = np.array([[27.38617401, 0.0, 0.0], [0.0, 18.81922578, 0.0],
                             [0.0, 0.0, 0.08160226]])
    result__0_10 = np.array([[28.91067234, 0.0, 0.0], [0.0, 20.21670386, 0.0],
                             [0.0, 0.0, 0.08892512]])

    atol = 1.0e-8
    rtol = 0.0
    np.testing.assert_allclose(driver.results[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    mol = molecules.molecule_water_sto3g()
    mol.build()
    polarizability = electric.Polarizability(
        Program.PySCF,
        mol,
        cphf.CPHF(solvers.ExactInv(C, E, occupations)),
        C,
        E,
        occupations,
        frequencies=frequencies,
    )
    polarizability.form_operators()
    polarizability.run(hamiltonian=hamiltonian, spin=spin)
    polarizability.form_results()

    np.testing.assert_allclose(polarizability.polarizabilities[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)
示例#24
0
def test_ECD_RPA_singlet_BC2H4_cation_HF_STO3G():

    ref = BC2H4_cation_HF_STO3G_RPA_singlet_nwchem
    nroots = ref["nroots"]

    mol = molecules.molecule_bc2h4_cation_sto3g()
    mol.build()

    mf = pyscf.scf.RHF(mol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = utils.occupations_from_pyscf_mol(mol, C)

    ecd_dipvel_rpa = ecd.ECD(Program.PySCF, mol, C, E, occupations, do_dipvel=True)
    ecd_dipvel_rpa.form_operators()
    ecd_dipvel_rpa.run(hamiltonian="rpa", spin="singlet")
    ecd_dipvel_rpa.form_results()

    print("excitation energies")
    ref_etenergies = np.array(ref["etenergies"])
    res_etenergies = ecd_dipvel_rpa.driver.solver.eigvals.real[:nroots]
    print("ref, res")
    for refval, resval in zip(ref_etenergies, res_etenergies):
        print(refval, resval)
    thresh = 1.0e-7
    for i in range(nroots):
        abs_diff = abs(ref_etenergies[i] - res_etenergies[i])
        assert abs_diff < thresh

    print("dipole (length) oscillator strengths")
    ref_etoscslen = np.array(ref["etoscslen"])
    res_etoscslen = ecd_dipvel_rpa.driver.solver.operators[1].total_oscillator_strengths[
        :nroots
    ]
    print("ref, res")
    for refval, resval in zip(ref_etoscslen, res_etoscslen):
        print(refval, resval)
    thresh = 1.0e-5
    for i in range(nroots):
        abs_diff = abs(ref_etoscslen[i] - res_etoscslen[i])
        assert abs_diff < thresh

    # TODO
    print("TODO dipole (mixed length/velocity) oscillator strengths")

    # TODO
    print("TODO dipole (velocity) oscillator strengths")
    ref_etoscsvel = np.array(ref["etoscsvel"])
    res_etoscsvel = ecd_dipvel_rpa.driver.solver.operators[2].total_oscillator_strengths[
        :nroots
    ]
    # print('ref, res')
    # for refval, resval in zip(ref_etoscsvel, res_etoscsvel):
    #     print(refval, resval)
    # print(ref_etoscsvel / res_etoscsvel)
    # print(res_etoscsvel / ref_etoscsvel)

    print("rotatory strengths (length)")
    ref_etrotstrlen = np.array(ref["etrotstrlen"])
    res_etrotstrlen = ecd_dipvel_rpa.rotational_strengths_diplen[:nroots]
    print("ref, res")
    for refval, resval in zip(ref_etrotstrlen, res_etrotstrlen):
        print(refval, resval)
    # TODO unlike other quantities, the error isn't uniformly
    # distributed among the roots; how should this be handled?
    thresh = 1.5e1
    for i in range(nroots):
        abs_diff = abs(ref_etrotstrlen[i] - res_etrotstrlen[i])
        assert abs_diff < thresh

    print("rotatory strengths (velocity)")
    ref_etrotstrvel = np.array(ref["etrotstrvel"])
    res_etrotstrvel = ecd_dipvel_rpa.rotational_strengths_dipvel[:nroots]
    print("ref, res")
    for refval, resval in zip(ref_etrotstrvel, res_etrotstrvel):
        print(refval, resval)
    thresh = 1.0e-2
    for i in range(nroots):
        abs_diff = abs(ref_etrotstrvel[i] - res_etrotstrvel[i])
        assert abs_diff < thresh

    # with open(os.path.join(refdir, 'BC2H4_cation', 'nwchem_singlet_rpa_velocity_root.str')) as fh:
    #     ref_str = fh.read()
    # res_str = ecd_dipvel_rpa.print_results_nwchem()
    # assert res_str == ref_str
    # print(ecd_dipvel_rpa.print_results_nwchem())
    # print(ecd_dipvel_rpa.print_results_orca())
    # print(ecd_dipvel_rpa.print_results_qchem())

    # tmom_diplen = ecd_dipvel_rpa.driver.solver.operators[1].transition_moments
    # tmom_dipvel = ecd_dipvel_rpa.driver.solver.operators[2].transition_moments
    # print(tmom_diplen)
    # print('dipole')
    # for i in range(nroots):
    #     print((2 / 3) * res_etenergies[i] * np.dot(tmom_diplen[i], tmom_diplen[i]))
    # print('mixed')
    # for i in range(nroots):
    #     print((2 / 3) * res_etenergies[i] * np.dot(tmom_diplen[i], tmom_dipvel[i]))

    # print('sum rule')
    # print('ref_etoscslen:', sum(ref_etoscslen))
    # print('res_etoscslen:', sum(res_etoscslen))
    # # print('ref_etoscsmix:', sum(ref_etoscsmix))
    # # print('res_etoscsmix:', sum(res_etoscsmix))
    # print('ref_etoscsvel:', sum(ref_etoscsvel))
    # print('res_etoscsvel:', sum(res_etoscsvel))

    return
示例#25
0
def test_first_hyperpolarizability_or_rhf_wigner_explicit():
    mol = molecule_water_sto3g_angstrom()
    mol.build()

    mf = pyscf.scf.RHF(mol)
    mf.kernel()
    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = utils.occupations_from_pyscf_mol(mol, C)
    nocc_alph, nvirt_alph, _, _ = occupations
    nov_alph = nocc_alph * nvirt_alph
    norb = nocc_alph + nvirt_alph

    # calculate linear response vectors for electric dipole operator
    f1 = 0.0
    f2 = 0.0773178
    frequencies = [f1, f2]
    calculator = electric.Polarizability(Program.PySCF,
                                         mol,
                                         C,
                                         E,
                                         occupations,
                                         frequencies=frequencies)
    calculator.form_operators()
    calculator.run()
    calculator.form_results()

    polarizability_1 = calculator.polarizabilities[0]
    polarizability_2 = calculator.polarizabilities[1]
    print("polarizability (static)")
    print(polarizability_1)
    print("polarizability: {} a.u.".format(f2))
    print(polarizability_2)

    # each operator contains multiple sets of response vectors, one
    # set of components for each frequency
    assert isinstance(calculator.driver.solver.operators, list)
    assert len(calculator.driver.solver.operators) == 1
    operator = calculator.driver.solver.operators[0]
    rhsvecs = operator.mo_integrals_ai_supervector_alph
    assert isinstance(operator.rspvecs_alph, list)
    assert len(operator.rspvecs_alph) == 2
    rspvecs_1 = operator.rspvecs_alph[0]
    rspvecs_2 = operator.rspvecs_alph[1]

    ## Form the full [norb, norb] representation of everything.
    # Response vectors: transform X_{ia} and Y_{ia} -> U_{p,q}
    # 0. 'a' is fast index, 'i' slow
    # 1. rspvec == [X Y]
    # 2. U_{p, q} -> zero
    # 3. place X_{ia} into U_{i, a}
    # 4. place Y_{ia} into U_{a, i}

    ncomp = rhsvecs.shape[0]

    rspmats_1 = np.zeros(shape=(ncomp, norb, norb))
    rspmats_2 = np.zeros(shape=(ncomp, norb, norb))
    for i in range(ncomp):
        rspvec_1 = rspvecs_1[i, :, 0]
        rspvec_2 = rspvecs_2[i, :, 0]
        x_1 = rspvec_1[:nov_alph]
        y_1 = rspvec_1[nov_alph:]
        x_2 = rspvec_2[:nov_alph]
        y_2 = rspvec_2[nov_alph:]
        x_full_1 = utils.repack_vector_to_matrix(x_1, (nvirt_alph, nocc_alph))
        y_full_1 = utils.repack_vector_to_matrix(y_1, (nvirt_alph, nocc_alph))
        x_full_2 = utils.repack_vector_to_matrix(x_2, (nvirt_alph, nocc_alph))
        y_full_2 = utils.repack_vector_to_matrix(y_2, (nvirt_alph, nocc_alph))
        rspmats_1[i, :nocc_alph, nocc_alph:] = y_full_1.T
        rspmats_1[i, nocc_alph:, :nocc_alph] = x_full_1
        rspmats_2[i, :nocc_alph, nocc_alph:] = y_full_2.T
        rspmats_2[i, nocc_alph:, :nocc_alph] = x_full_2

    rhsmats = np.zeros(shape=(ncomp, norb, norb))
    for i in range(ncomp):
        rhsvec = rhsvecs[i, :, 0]
        rhsvec_top = rhsvec[:nov_alph]
        rhsvec_bot = rhsvec[nov_alph:]
        rhsvec_top_mat = utils.repack_vector_to_matrix(rhsvec_top,
                                                       (nvirt_alph, nocc_alph))
        rhsvec_bot_mat = utils.repack_vector_to_matrix(rhsvec_bot,
                                                       (nvirt_alph, nocc_alph))
        rhsmats[i, :nocc_alph, nocc_alph:] = rhsvec_top_mat.T
        rhsmats[i, nocc_alph:, :nocc_alph] = rhsvec_bot_mat

    polarizability_full_1 = np.empty_like(polarizability_1)
    polarizability_full_2 = np.empty_like(polarizability_2)
    for a in (0, 1, 2):
        for b in (0, 1, 2):
            polarizability_full_1[a, b] = 2 * np.trace(rhsmats[a, ...].T.dot(
                rspmats_1[b, ...]))
            polarizability_full_2[a, b] = 2 * np.trace(rhsmats[a, ...].T.dot(
                rspmats_2[b, ...]))

    np.testing.assert_almost_equal(polarizability_1, -polarizability_full_1)
    np.testing.assert_almost_equal(polarizability_2, -polarizability_full_2)

    # V_{p,q} <- full MO transformation of right hand side
    integrals_ao = operator.ao_integrals
    integrals_mo = np.empty_like(integrals_ao)
    for i in range(ncomp):
        integrals_mo[i, ...] = (C[0, ...].T).dot(integrals_ao[i,
                                                              ...]).dot(C[0,
                                                                          ...])

    # from pyresponse.ao2mo import AO2MOpyscf
    # ao2mo = AO2MOpyscf(C, pyscfmol=mol)
    # ao2mo.perform_rhf_full()
    # tei_mo = ao2mo.tei_mo[0]

    G_1 = np.empty_like(rspmats_1)
    G_2 = np.empty_like(rspmats_2)
    C = mf.mo_coeff
    # TODO I feel as though if I have all the MO-basis two-electron
    # integrals, I shouldn't need another JK build.
    for i in range(ncomp):
        V = integrals_mo[i, ...]
        Dl_1 = (C[:, :nocc_alph]).dot(rspmats_1[i, :nocc_alph, :]).dot(C.T)
        Dr_1 = (-C).dot(rspmats_1[i, :, :nocc_alph]).dot(C[:, :nocc_alph].T)
        D_1 = Dl_1 + Dr_1
        Dl_2 = (C[:, :nocc_alph]).dot(rspmats_2[i, :nocc_alph, :]).dot(C.T)
        Dr_2 = (-C).dot(rspmats_2[i, :, :nocc_alph]).dot(C[:, :nocc_alph].T)
        D_2 = Dl_2 + Dr_2
        J_1, K_1 = mf.get_jk(mol, D_1, hermi=0)
        J_2, K_2 = mf.get_jk(mol, D_2, hermi=0)
        F_AO_1 = 2 * J_1 - K_1
        F_AO_2 = 2 * J_2 - K_2
        F_MO_1 = (C.T).dot(F_AO_1).dot(C)
        F_MO_2 = (C.T).dot(F_AO_2).dot(C)
        G_1[i, ...] = V + F_MO_1
        G_2[i, ...] = V + F_MO_2

    E_diag = np.diag(E[0, ...])
    epsilon_1 = G_1.copy()
    epsilon_2 = G_2.copy()
    for i in range(ncomp):
        eoU_1 = (E_diag[..., np.newaxis] + f1) * rspmats_1[i, ...]
        Ue_1 = rspmats_1[i, ...] * E_diag[np.newaxis, ...]
        epsilon_1[i, ...] += eoU_1 - Ue_1
        eoU_2 = (E_diag[..., np.newaxis] + f2) * rspmats_2[i, ...]
        Ue_2 = rspmats_2[i, ...] * E_diag[np.newaxis, ...]
        epsilon_2[i, ...] += eoU_2 - Ue_2

    # Assume some symmetry and calculate only part of the tensor.

    hyperpolarizability = np.zeros(shape=(6, 3))
    off1 = [0, 1, 2, 0, 0, 1]
    off2 = [0, 1, 2, 1, 2, 2]
    for r in range(6):
        b = off1[r]
        c = off2[r]
        for a in range(3):
            # _1 -> 0
            # _2 -> +w
            # a is _1, b is _2, c is _2 transposed/negated
            tl1 = np.trace(rspmats_1[a, ...].dot(G_2[b, ...]).dot(
                rspmats_2[c, ...].T)[:nocc_alph, :nocc_alph])
            tl2 = np.trace(rspmats_2[c, ...].T.dot(G_2[b, ...]).dot(
                rspmats_1[a, ...])[:nocc_alph, :nocc_alph])
            tl3 = np.trace(rspmats_1[a, ...].dot(-G_2[c, ...].T).dot(
                rspmats_2[b, ...])[:nocc_alph, :nocc_alph])
            tl4 = np.trace(rspmats_2[b, ...].dot(-G_2[c, ...].T).dot(
                rspmats_1[a, ...])[:nocc_alph, :nocc_alph])
            tl5 = np.trace(rspmats_2[c, ...].T.dot(G_1[a, ...]).dot(
                rspmats_2[b, ...])[:nocc_alph, :nocc_alph])
            tl6 = np.trace(rspmats_2[b, ...].dot(G_1[a, ...]).dot(
                rspmats_2[c, ...].T)[:nocc_alph, :nocc_alph])
            tr1 = np.trace(rspmats_2[c, ...].T.dot(rspmats_2[b, ...]).dot(
                epsilon_1[a, ...])[:nocc_alph, :nocc_alph])
            tr2 = np.trace(rspmats_2[b, ...].dot(rspmats_2[c, ...].T).dot(
                epsilon_1[a, ...])[:nocc_alph, :nocc_alph])
            tr3 = np.trace(rspmats_2[c, ...].T.dot(rspmats_1[a, ...]).dot(
                epsilon_2[b, ...])[:nocc_alph, :nocc_alph])
            tr4 = np.trace(rspmats_1[a, ...].dot(rspmats_2[c, ...].T).dot(
                epsilon_2[b, ...])[:nocc_alph, :nocc_alph])
            tr5 = np.trace(rspmats_2[b, ...].dot(
                rspmats_1[a,
                          ...]).dot(-epsilon_2[c,
                                               ...].T)[:nocc_alph, :nocc_alph])
            tr6 = np.trace(rspmats_1[a, ...].dot(
                rspmats_2[b,
                          ...]).dot(-epsilon_2[c,
                                               ...].T)[:nocc_alph, :nocc_alph])
            tl = tl1 + tl2 + tl3 + tl4 + tl5 + tl6
            tr = tr1 + tr2 + tr3 + tr4 + tr5 + tr6
            hyperpolarizability[r, a] = -2 * (tl - tr)

    # pylint: disable=C0326
    ref = np.array([
        [-9.02854579, 0.92998934, -0.52377445],
        [2.01080066, 5.23470702, -3.01208409],
        [0.66669794, 1.66112712, -0.87205853],
        [0.92021130, 2.01769267, -1.11067223],
        [-0.51824440, -1.11067586, 0.67140102],
        [-1.10887175, -3.00950655, 1.65659586],
    ])
    ref_avgs = np.array([6.34331713, -7.81628395, 4.40251201])
    ref_avg = 10.98699590

    thresh = 4.0e-5
    assert np.all(np.abs(ref - hyperpolarizability) < thresh)

    print("hyperpolarizability: OR, (0; {}, -{}), symmetry-unique components".
          format(f2, f2))
    print(hyperpolarizability)

    return
示例#26
0
def test_ECD_TDA_singlet_BC2H4_cation_HF_STO3G():

    ref = BC2H4_cation_HF_STO3G_TDA_singlet_orca
    nroots = ref["nroots"]

    mol = molecules.molecule_bc2h4_cation_sto3g()
    mol.build()

    mf = pyscf.scf.RHF(mol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = utils.occupations_from_pyscf_mol(mol, C)

    ecd_dipvel_tda = ecd.ECD(Program.PySCF, mol, C, E, occupations, do_dipvel=True)
    ecd_dipvel_tda.form_operators()
    ecd_dipvel_tda.run(hamiltonian="tda", spin="singlet")
    ecd_dipvel_tda.form_results()

    print("excitation energies")
    ref_etenergies = np.array(ref["etenergies"])
    res_etenergies = ecd_dipvel_tda.driver.solver.eigvals.real[:nroots]
    print("ref, res")
    for refval, resval in zip(ref_etenergies, res_etenergies):
        print(refval, resval)
    # TODO this might be from ORCA, should use NWChem instead
    thresh = 1.0e-3
    for i in range(nroots):
        abs_diff = abs(ref_etenergies[i] - res_etenergies[i])
        assert abs_diff < thresh

    print("dipole (length) oscillator strengths")
    ref_etoscslen = np.array(ref["etoscslen"])
    res_etoscslen = ecd_dipvel_tda.driver.solver.operators[1].total_oscillator_strengths[
        :nroots
    ]
    print("ref, res")
    for refval, resval in zip(ref_etoscslen, res_etoscslen):
        print(refval, resval)
    thresh = 1.0e-3
    # np.testing.assert_allclose(ref_etoscslen, res_etoscslen)
    for i in range(nroots):
        abs_diff = abs(ref_etoscslen[i] - res_etoscslen[i])
        assert abs_diff < thresh

    # TODO
    print("TODO dipole (mixed length/velocity) oscillator strengths")

    # TODO
    print("TODO dipole (velocity) oscillator strengths")

    print("rotatory strengths (length)")
    ref_etrotstrlen = np.array(ref["etrotstrlen"])
    res_etrotstrlen = ecd_dipvel_tda.rotational_strengths_diplen[:nroots]
    print("ref, res")
    for refval, resval in zip(ref_etrotstrlen, res_etrotstrlen):
        print(refval, resval)
    # TODO unlike other quantities, the error isn't uniformly
    # distributed among the roots; how should this be handled?
    thresh = 1.0e2
    for i in range(nroots):
        abs_diff = abs(ref_etrotstrlen[i] - res_etrotstrlen[i])
        assert abs_diff < thresh

    # print('rotatory strengths (velocity)')
    # ref_etrotstrvel = np.array(ref['etrotstrvel'])
    # res_etrotstrvel = ecd_dipvel_tda.rotational_strengths_dipvel[:nroots]
    # print('ref, res')
    # for refval, resval in zip(ref_etrotstrvel, res_etrotstrvel):
    #     print(refval, resval)
    # thresh = 1.0e-2
    # for i in range(nroots):
    #     abs_diff = abs(ref_etrotstrvel[i] - res_etrotstrvel[i])
    #     assert abs_diff < thresh

    # print(ecd_dipvel_tda.print_results_nwchem())
    # print(ecd_dipvel_tda.print_results_orca())
    # print(ecd_dipvel_tda.print_results_qchem())

    return
示例#27
0
def test_final_result_rhf_h2o_sto3g_tda_triplet():
    hamiltonian = "tda"
    spin = "triplet"

    C = utils.fix_mocoeffs_shape(utils.np_load(REFDIR / "C.npz"))
    E = utils.fix_moenergies_shape(utils.np_load(REFDIR / "F_MO.npz"))
    TEI_MO = utils.np_load(REFDIR / "TEI_MO.npz")
    # nocc_alph, nvirt_alph, nocc_beta, nvirt_beta
    occupations = [5, 2, 5, 2]
    stub = "h2o_sto3g_"
    dim = occupations[0] + occupations[1]
    mat_dipole_x = utils.parse_int_file_2(REFDIR / f"{stub}mux.dat", dim)
    mat_dipole_y = utils.parse_int_file_2(REFDIR / f"{stub}muy.dat", dim)
    mat_dipole_z = utils.parse_int_file_2(REFDIR / f"{stub}muz.dat", dim)

    solver = iterators.ExactInv(C, E, occupations)
    solver.tei_mo = (TEI_MO, )
    solver.tei_mo_type = "full"
    driver = cphf.CPHF(solver)
    ao_integrals_dipole = np.stack((mat_dipole_x, mat_dipole_y, mat_dipole_z),
                                   axis=0)
    operator_dipole = operators.Operator(label="dipole",
                                         is_imaginary=False,
                                         is_spin_dependent=False)
    operator_dipole.ao_integrals = ao_integrals_dipole
    driver.add_operator(operator_dipole)
    frequencies = (0.0, 0.02, 0.06, 0.1)
    driver.set_frequencies(frequencies)

    driver.run(solver_type="exact", hamiltonian=hamiltonian, spin=spin)

    assert len(driver.results) == len(frequencies)

    result__0_00 = np.array([[14.64430714, 0.0, 0.0], [0.0, 8.80921432, 0.0],
                             [0.0, 0.0, 0.06859496]])
    result__0_02 = np.array([[14.68168443, 0.0, 0.0], [0.0, 8.83562647, 0.0],
                             [0.0, 0.0, 0.0689291]])
    result__0_06 = np.array([[14.98774296, 0.0, 0.0], [0.0, 9.0532224, 0.0],
                             [0.0, 0.0, 0.07172414]])
    result__0_10 = np.array([[15.63997724, 0.0, 0.0], [0.0, 9.52504267, 0.0],
                             [0.0, 0.0, 0.07805428]])

    atol = 1.0e-8
    rtol = 0.0
    np.testing.assert_allclose(driver.results[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    mol = molecules.molecule_water_sto3g()
    mol.build()
    polarizability = electric.Polarizability(Program.PySCF, mol, C, E,
                                             occupations, frequencies)
    polarizability.form_operators()
    polarizability.run(hamiltonian=hamiltonian, spin=spin)
    polarizability.form_results()

    np.testing.assert_allclose(polarizability.polarizabilities[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    return
示例#28
0
def test_final_result_rhf_h2o_sto3g_tda_singlet():
    hamiltonian = "tda"
    spin = "singlet"

    C = utils.fix_mocoeffs_shape(utils.np_load(REFDIR / "C.npz"))
    E = utils.fix_moenergies_shape(utils.np_load(REFDIR / "F_MO.npz"))
    TEI_MO = utils.np_load(REFDIR / "TEI_MO.npz")
    # nocc_alph, nvirt_alph, nocc_beta, nvirt_beta
    occupations = [5, 2, 5, 2]
    stub = "h2o_sto3g_"
    dim = occupations[0] + occupations[1]
    mat_dipole_x = utils.parse_int_file_2(REFDIR / f"{stub}mux.dat", dim)
    mat_dipole_y = utils.parse_int_file_2(REFDIR / f"{stub}muy.dat", dim)
    mat_dipole_z = utils.parse_int_file_2(REFDIR / f"{stub}muz.dat", dim)

    solver = iterators.ExactInv(C, E, occupations)
    solver.tei_mo = (TEI_MO, )
    solver.tei_mo_type = "full"
    driver = cphf.CPHF(solver)
    ao_integrals_dipole = np.stack((mat_dipole_x, mat_dipole_y, mat_dipole_z),
                                   axis=0)
    operator_dipole = operators.Operator(label="dipole",
                                         is_imaginary=False,
                                         is_spin_dependent=False)
    operator_dipole.ao_integrals = ao_integrals_dipole
    driver.add_operator(operator_dipole)
    frequencies = (0.0, 0.02, 0.06, 0.1)
    driver.set_frequencies(frequencies)

    driver.run(solver_type="exact", hamiltonian=hamiltonian, spin=spin)

    assert len(driver.results) == len(frequencies)

    result__0_00 = np.array([[8.89855952, 0.0, 0.0], [0.0, 4.00026556, 0.0],
                             [0.0, 0.0, 0.0552774]])
    result__0_02 = np.array([[8.90690928, 0.0, 0.0], [0.0, 4.00298342, 0.0],
                             [0.0, 0.0, 0.05545196]])
    result__0_06 = np.array([[8.97427725, 0.0, 0.0], [0.0, 4.02491517, 0.0],
                             [0.0, 0.0, 0.05688918]])
    result__0_10 = np.array([[9.11212633, 0.0, 0.0], [0.0, 4.06981937, 0.0],
                             [0.0, 0.0, 0.05999934]])

    atol = 1.0e-8
    rtol = 0.0
    np.testing.assert_allclose(driver.results[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    mol = molecules.molecule_water_sto3g()
    mol.build()
    polarizability = electric.Polarizability(Program.PySCF, mol, C, E,
                                             occupations, frequencies)
    polarizability.form_operators()
    polarizability.run(hamiltonian=hamiltonian, spin=spin)
    polarizability.form_results()

    np.testing.assert_allclose(polarizability.polarizabilities[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    return
示例#29
0
def test_ORD_RPA_singlet_trithiolane_HF_STO3G():

    ref = trithiolane_HF_STO3G_RPA_singlet

    pyscfmol = molecules.molecule_trithiolane_sto3g()
    pyscfmol.build()

    mf = pyscf.scf.RHF(pyscfmol)
    mf.scf()

    C = utils.fix_mocoeffs_shape(mf.mo_coeff)
    E = utils.fix_moenergies_shape(mf.mo_energy)
    occupations = utils.occupations_from_pyscf_mol(pyscfmol, C)

    frequencies = [0.0, 0.0773178, 0.128347]
    ord_solver = optrot.ORD(
        Program.PySCF,
        pyscfmol,
        C,
        E,
        occupations,
        frequencies=frequencies,
        do_dipvel=False,
    )
    ord_solver.form_operators()
    ord_solver.run(hamiltonian="rpa", spin="singlet")
    ord_solver.form_results()

    print("Polarizabilities")
    assert len(frequencies) == len(ord_solver.polarizabilities)
    thresh = 5.0e-4
    for idxf, frequency in enumerate(frequencies):
        ref_polar = ref[frequency]["polar"]
        res_polar = ord_solver.polarizabilities[idxf]
        abs_diff = abs(res_polar - ref_polar)
        print(idxf, frequency)
        print(res_polar)
        print(abs_diff)
        assert (abs_diff < thresh).all()

    # print('Electric dipole-magnetic dipole polarizabilities')
    # assert len(frequencies) == len(ord_solver.polarizabilities_lenmag)
    # # thresh
    # for idxf, frequency in enumerate(frequencies):
    #     if 'dipmag' in ref[frequency]:
    #         ref_dipmag = ref[frequency]['dipmag']
    #         res_dipmag = ord_solver.polarizabilities_lenmag[idxf]
    #         print(idxf, frequency)
    #         # print(ref_dipmag)
    #         # print(res_dipmag)
    #         print(res_dipmag / ref_dipmag)

    # print(r'\beta(\omega)')
    # thresh = 5.0e-2
    # for idxf, frequency in enumerate(frequencies):
    #     if 'orbeta' in ref[frequency]:
    #         ref_beta = ref[frequency]['orbeta']
    #         # why no speed of light? atomic units...
    #         # TODO why the (1/2)?
    #         res_beta = -(0.5 / frequency) * ord_solver.solver.results[idxf][3:6, 0:3]
    #         abs_diff = abs(res_beta - ref_beta)
    #         print(idxf, frequency)
    #         print(res_beta)
    #         print(abs_diff)
    #         assert (abs_diff < thresh).all()

    return
示例#30
0
def test_final_result_rhf_h2o_sto3g_rpa_triplet():
    hamiltonian = "rpa"
    spin = "triplet"

    C = utils.fix_mocoeffs_shape(utils.np_load(REFDIR / "C.npz"))
    E = utils.fix_moenergies_shape(utils.np_load(REFDIR / "F_MO.npz"))
    TEI_MO = utils.np_load(REFDIR / "TEI_MO.npz")
    # nocc_alph, nvirt_alph, nocc_beta, nvirt_beta
    occupations = [5, 2, 5, 2]
    stub = "h2o_sto3g_"
    dim = occupations[0] + occupations[1]
    mat_dipole_x = utils.parse_int_file_2(REFDIR / f"{stub}mux.dat", dim)
    mat_dipole_y = utils.parse_int_file_2(REFDIR / f"{stub}muy.dat", dim)
    mat_dipole_z = utils.parse_int_file_2(REFDIR / f"{stub}muz.dat", dim)

    solver = iterators.ExactInv(C, E, occupations)
    solver.tei_mo = (TEI_MO, )
    solver.tei_mo_type = "full"
    driver = cphf.CPHF(solver)
    ao_integrals_dipole = np.stack((mat_dipole_x, mat_dipole_y, mat_dipole_z),
                                   axis=0)
    operator_dipole = operators.Operator(label="dipole",
                                         is_imaginary=False,
                                         is_spin_dependent=False)
    operator_dipole.ao_integrals = ao_integrals_dipole
    driver.add_operator(operator_dipole)
    frequencies = (0.0, 0.02, 0.06, 0.1)
    driver.set_frequencies(frequencies)

    driver.run(solver_type="exact", hamiltonian=hamiltonian, spin=spin)

    assert len(driver.results) == len(frequencies)

    result__0_00 = np.array([[26.59744305, 0.0, 0.0], [0.0, 18.11879557, 0.0],
                             [0.0, 0.0, 0.07798969]])
    result__0_02 = np.array([[26.68282287, 0.0, 0.0], [0.0, 18.19390051, 0.0],
                             [0.0, 0.0, 0.07837521]])
    result__0_06 = np.array([[27.38617401, 0.0, 0.0], [0.0, 18.81922578, 0.0],
                             [0.0, 0.0, 0.08160226]])
    result__0_10 = np.array([[28.91067234, 0.0, 0.0], [0.0, 20.21670386, 0.0],
                             [0.0, 0.0, 0.08892512]])

    atol = 1.0e-8
    rtol = 0.0
    np.testing.assert_allclose(driver.results[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(driver.results[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    mol = molecules.molecule_water_sto3g()
    mol.build()
    polarizability = electric.Polarizability(Program.PySCF, mol, C, E,
                                             occupations, frequencies)
    polarizability.form_operators()
    polarizability.run(hamiltonian=hamiltonian, spin=spin)
    polarizability.form_results()

    np.testing.assert_allclose(polarizability.polarizabilities[0],
                               result__0_00,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[1],
                               result__0_02,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[2],
                               result__0_06,
                               rtol=rtol,
                               atol=atol)
    np.testing.assert_allclose(polarizability.polarizabilities[3],
                               result__0_10,
                               rtol=rtol,
                               atol=atol)

    return