Пример #1
0
 def template_pe_formaldehyde(self, basis, method, backend):
     basename = f"formaldehyde_{basis}_pe_{method}"
     qc_result = qchem_data[basename]
     pe_options = {"potfile": pe_potentials["fa_6w"]}
     scfres = cached_backend_hf(backend,
                                "formaldehyde",
                                basis,
                                pe_options=pe_options)
     state = adcc.run_adc(scfres,
                          method=method,
                          n_singlets=5,
                          conv_tol=1e-10)
     assert_allclose(qc_result["excitation_energy"],
                     state.excitation_energy_uncorrected,
                     atol=1e-5)
     assert_allclose(+qc_result["excitation_energy"] +
                     qc_result["pe_ptss_correction"] +
                     qc_result["pe_ptlr_correction"],
                     state.excitation_energy,
                     atol=1e-5)
     assert_allclose(qc_result["pe_ptss_correction"],
                     state.pe_ptss_correction,
                     atol=1e-5)
     assert_allclose(qc_result["pe_ptlr_correction"],
                     state.pe_ptlr_correction,
                     atol=1e-5)
Пример #2
0
    def template_pcm_ptlr_formaldehyde(self, basis, method, backend):
        if method != "adc1":
            pytest.skip("Data only available for adc1.")

        c = config[backend]
        basename = f"formaldehyde_{basis}_pcm_{method}"
        result = c["data"][basename]

        run_hf = c["run_hf"]
        scfres = run_hf(static_data.xyz["formaldehyde"], basis, charge=0,
                        multiplicity=1, conv_tol=1e-12, conv_tol_grad=1e-11,
                        max_iter=150, pcm_options=c["pcm_options"])

        assert_allclose(scfres.energy_scf, result["energy_scf"], atol=1e-8)

        state = adcc.run_adc(scfres, method=method, n_singlets=5,
                             conv_tol=1e-7, environment="ptlr")

        # compare ptLR result to LR data
        assert_allclose(state.excitation_energy,
                        result["lr_excitation_energy"], atol=5e-3)

        # Consistency check with values obtained with ADCc
        assert_allclose(state.excitation_energy,
                        result["ptlr_adcc_excitation_energy"], atol=1e-6)

        if backend == "psi4":
            # remove cavity files from PSI4 PCM calculations
            remove_cavity_psi4()
Пример #3
0
 def template_test_h2o_sto3g(self, method):
     scfres = self._run_scf_h2o_sto3g()
     if "cvs" in method:
         refstate = adcc.ReferenceState(scfres, core_orbitals=1)
         n_states = 2
     else:
         refstate = adcc.ReferenceState(scfres)
         n_states = 3
     state_singlets = adcc.run_adc(refstate, method=method,
                                   n_singlets=n_states, conv_tol=self.conv_tol)
     assert np.all(_residual_norms(state_singlets) < self.conv_tol)
     state_triplets = adcc.run_adc(refstate, method=method,
                                   n_triplets=n_states, conv_tol=self.conv_tol)
     assert np.all(_residual_norms(state_triplets) < self.conv_tol)
     assert_allclose(state_singlets.excitation_energy,
                     _singlets[method], atol=self.conv_tol * 10)
     assert_allclose(state_triplets.excitation_energy,
                     _triplets[method], atol=self.conv_tol * 10)
Пример #4
0
    def template_pcm_linear_response_formaldehyde(self, basis, method, backend):
        if method != "adc1":
            pytest.skip("Reference only exists for adc1.")

        c = config[backend]
        basename = f"formaldehyde_{basis}_pcm_{method}"
        result = c["data"][basename]

        run_hf = c["run_hf"]
        scfres = run_hf(static_data.xyz["formaldehyde"], basis, charge=0,
                        multiplicity=1, conv_tol=1e-12, conv_tol_grad=1e-11,
                        max_iter=150, pcm_options=c["pcm_options"])

        assert_allclose(scfres.energy_scf, result["energy_scf"], atol=1e-8)

        matrix = adcc.AdcMatrix(method, scfres)
        solvent = AdcExtraTerm(matrix, {'ph_ph': block_ph_ph_0_pcm})

        matrix += solvent
        assert len(matrix.extra_terms)

        state = adcc.run_adc(matrix, n_singlets=5, conv_tol=1e-7,
                             environment=False)
        assert_allclose(
            state.excitation_energy_uncorrected,
            result["lr_excitation_energy"],
            atol=1e-5
        )

        state_cis = adcc.ExcitedStates(state, property_method="adc0")
        assert_allclose(
            state_cis.oscillator_strength,
            result["lr_osc_strength"], atol=1e-3
        )

        # invalid combination
        with pytest.raises(InputError):
            adcc.run_adc(scfres, method=method, n_singlets=5,
                         environment={"linear_response": True, "ptlr": True})

        # no environment specified
        with pytest.raises(InputError):
            adcc.run_adc(scfres, method=method, n_singlets=5)

        # automatically add coupling term
        state = adcc.run_adc(scfres, method=method, n_singlets=5,
                             conv_tol=1e-7, environment="linear_response")
        assert_allclose(
            state.excitation_energy_uncorrected,
            result["lr_excitation_energy"],
            atol=1e-5
        )

        if backend == "psi4":
            # remove cavity files from PSI4 PCM calculations
            remove_cavity_psi4()
Пример #5
0
    def template_pe_linear_response_formaldehyde(self, basis, method, backend):
        if method != "adc2":
            pytest.skip("Reference only exists for adc2.")
        basename = f"formaldehyde_{basis}_pe_{method}"
        tm_result = tmole_data[basename]
        pe_options = {"potfile": pe_potentials["fa_6w"]}
        scfres = cached_backend_hf(backend,
                                   "formaldehyde",
                                   basis,
                                   pe_options=pe_options)
        assert_allclose(scfres.energy_scf, tm_result["energy_scf"], atol=1e-8)

        matrix = adcc.AdcMatrix(method, scfres)
        solvent = AdcExtraTerm(matrix, {'ph_ph': block_ph_ph_0_pe})

        # manually add the coupling term
        matrix += solvent
        assert len(matrix.extra_terms)

        assert_allclose(matrix.ground_state.energy(2),
                        tm_result["energy_mp2"],
                        atol=1e-8)
        state = adcc.run_adc(matrix,
                             n_singlets=5,
                             conv_tol=1e-7,
                             environment=False)
        assert_allclose(state.excitation_energy_uncorrected,
                        tm_result["excitation_energy"],
                        atol=1e-6)

        # invalid combination
        with pytest.raises(InputError):
            adcc.run_adc(scfres,
                         method=method,
                         n_singlets=5,
                         environment={
                             "linear_response": True,
                             "ptlr": True
                         })
        # no scheme specified
        with pytest.raises(InputError):
            adcc.run_adc(scfres, method=method, n_singlets=5)

        # automatically add coupling term
        state = adcc.run_adc(scfres,
                             method=method,
                             n_singlets=5,
                             conv_tol=1e-7,
                             environment="linear_response")
        assert_allclose(state.excitation_energy_uncorrected,
                        tm_result["excitation_energy"],
                        atol=1e-6)
Пример #6
0
class TestAdcMatrixDenseExport(unittest.TestCase):
    def base_test(self, case, method, conv_tol=1e-8, **kwargs):
        kwargs.setdefault("n_states", 10)
        n_states = kwargs["n_states"]
        if "cvs" in method:
            refstate = cache.refstate_cvs[case]
        else:
            refstate = cache.refstate[case]

        matrix = adcc.AdcMatrix(method, refstate)
        state = adcc.run_adc(matrix, method=method, conv_tol=conv_tol, **kwargs)

        dense = matrix.to_dense_matrix()
        assert_allclose(dense, dense.T, rtol=1e-10, atol=1e-12)

        n_decimals = 10
        spectrum = np.linalg.eigvalsh(dense)
        rounded = np.unique(np.round(spectrum, n_decimals))[:n_states]
        assert_allclose(state.excitation_energies, rounded, atol=10 * conv_tol)
Пример #7
0
def run_adcc_ptlr(wfn):
    return adcc.run_adc(wfn,
                        method="adc1",
                        n_singlets=5,
                        conv_tol=1e-7,
                        environment="ptlr")
Пример #8
0
def dump_reference_adcc(data,
                        method,
                        dumpfile,
                        mp_tree="mp",
                        adc_tree="adc",
                        n_states_full=None,
                        n_guess_singles=None,
                        **kwargs):
    if isinstance(dumpfile, h5py.File):
        out = dumpfile
    elif isinstance(dumpfile, str):
        out = h5py.File(dumpfile, "w")
    else:
        raise TypeError(
            "Unknown type for out, only HDF5 file and str supported.")

    # TODO: spin-flip, etc.
    states = []
    if "n_states" in kwargs:
        state = adcc.run_adc(data, method=method, **kwargs)
        states.append(state)
    else:
        n_singlets = kwargs.pop("n_singlets", 0)
        n_triplets = kwargs.pop("n_triplets", 0)
        if n_singlets:
            state = adcc.run_adc(data,
                                 method=method,
                                 n_singlets=n_singlets,
                                 n_guesses=n_guess_singles,
                                 **kwargs)
            states.append(state)
        if n_triplets:
            state = adcc.run_adc(data,
                                 method=method,
                                 n_triplets=n_triplets,
                                 n_guesses=n_guess_singles,
                                 **kwargs)
            states.append(state)

    if not len(states):
        raise ValueError("No excited states obtained.")

    #
    # MP
    #
    mp = out.create_group(mp_tree)

    # obtain ground state
    ground_state = states[0].ground_state

    mp["mp2/energy"] = ground_state.energy_correction(2)
    if "cvs" not in method:
        # TODO: MP3 energy correction missing in adcc for cvs
        mp["mp3/energy"] = ground_state.energy_correction(3)

    mp["mp2/dipole"] = ground_state.dipole_moment(level=2)
    mp.create_dataset("mp1/t_o1o1v1v1",
                      data=ground_state.t2("o1o1v1v1").to_ndarray(),
                      compression=8)
    mp.create_dataset("mp1/df_o1v1",
                      data=ground_state.df("o1v1").to_ndarray(),
                      compression=8)
    if "cvs" not in method:
        # TODO: missing in adcc for cvs
        mp.create_dataset("mp2/td_o1o1v1v1",
                          data=ground_state.td2("o1o1v1v1").to_ndarray(),
                          compression=8)
    if ground_state.has_core_occupied_space:
        mp.create_dataset("mp1/t_o2o2v1v1",
                          data=ground_state.t2("o2o2v1v1").to_ndarray(),
                          compression=8)
        mp.create_dataset("mp1/t_o1o2v1v1",
                          data=ground_state.t2("o1o2v1v1").to_ndarray(),
                          compression=8)
        mp.create_dataset("mp1/df_o2v1",
                          data=ground_state.df("o2v1").to_ndarray(),
                          compression=8)

    for block in [
            "dm_o1o1", "dm_o1v1", "dm_v1v1", "dm_bb_a", "dm_bb_b", "dm_o2o1",
            "dm_o2o2", "dm_o2v1"
    ]:
        blk = block.split("_")[-1]
        if blk in ground_state.mp2_diffdm.blocks:
            mp.create_dataset("mp2/" + block,
                              compression=8,
                              data=ground_state.mp2_diffdm[blk].to_ndarray())

    #
    # ADC
    #
    adc = out.create_group(adc_tree)

    # Data for matrix tests
    gmatrix = adc.create_group("matrix")
    random_vector = adcc.copy(states[0].excitation_vector[0]).set_random()

    # Compute matvec and block-wise apply
    matvec = states[0].matrix.compute_matvec(random_vector)
    result = {
        "ss": adcc.copy(random_vector["s"]),
    }
    states[0].matrix.compute_apply("ss", random_vector["s"], result["ss"])
    if "d" in random_vector.blocks:
        if not ("cvs" in method and "adc3" in method):
            result["ds"] = adcc.copy(random_vector["d"])
            states[0].matrix.compute_apply("ds", random_vector["s"],
                                           result["ds"])
            result["sd"] = adcc.copy(random_vector["s"])
            states[0].matrix.compute_apply("sd", random_vector["d"],
                                           result["sd"])

        # TODO CVS-ADC(2)-x and CVS-ADC(3) compute_apply("dd") is not implemented
        if not ("cvs" in method and ("adc2x" in method or "adc3" in method)):
            result["dd"] = adcc.copy(random_vector["d"])
            states[0].matrix.compute_apply("dd", random_vector["d"],
                                           result["dd"])

    gmatrix["random_singles"] = random_vector["s"].to_ndarray()
    gmatrix["diagonal_singles"] = states[0].matrix.diagonal("s").to_ndarray()
    gmatrix["matvec_singles"] = matvec["s"].to_ndarray()
    gmatrix["result_ss"] = result["ss"].to_ndarray()
    if 'd' in random_vector.blocks:
        gmatrix.create_dataset("random_doubles",
                               compression=8,
                               data=random_vector["d"].to_ndarray())
        gmatrix.create_dataset(
            "diagonal_doubles",
            compression=8,
            data=states[0].matrix.diagonal("d").to_ndarray())
        gmatrix.create_dataset("matvec_doubles",
                               compression=8,
                               data=matvec["d"].to_ndarray())
        if "ds" in result:
            gmatrix.create_dataset("result_ds",
                                   compression=8,
                                   data=result["ds"].to_ndarray())
        if "sd" in result:
            gmatrix["result_sd"] = result["sd"].to_ndarray()
        if "dd" in result:
            gmatrix.create_dataset("result_dd",
                                   compression=8,
                                   data=result["dd"].to_ndarray())

    available_kinds = []
    for state in states:
        assert state.converged
        available_kinds.append(state.kind)
        dm_bb_a = []
        dm_bb_b = []
        tdm_bb_a = []
        tdm_bb_b = []
        eigenvectors_singles = []
        eigenvectors_doubles = []
        n_states = state.excitation_energy.size

        # Up to n_states_extract states we save everything
        if n_states_full is not None:
            n_states_extract = min(n_states_full, n_states)
        else:
            n_states_extract = n_states

        for i in range(n_states_extract):
            bb_a, bb_b = state.state_diffdm[i].to_ao_basis(
                state.reference_state)
            dm_bb_a.append(bb_a.to_ndarray())
            dm_bb_b.append(bb_b.to_ndarray())
            bb_a, bb_b = state.transition_dm[i].to_ao_basis(
                state.reference_state)
            tdm_bb_a.append(bb_a.to_ndarray())
            tdm_bb_b.append(bb_b.to_ndarray())

            eigenvectors_singles.append(
                state.excitation_vector[i]['s'].to_ndarray())
            if 'd' in state.excitation_vector[i].blocks:
                eigenvectors_doubles.append(
                    state.excitation_vector[i]['d'].to_ndarray())
            else:
                eigenvectors_doubles.clear()

        kind = state.kind
        # Transform to numpy array
        adc[kind + "/state_diffdm_bb_a"] = np.asarray(dm_bb_a)
        adc[kind + "/state_diffdm_bb_b"] = np.asarray(dm_bb_b)
        adc[kind + "/ground_to_excited_tdm_bb_a"] = np.asarray(tdm_bb_a)
        adc[kind + "/ground_to_excited_tdm_bb_b"] = np.asarray(tdm_bb_b)
        adc[kind + "/state_dipole_moments"] = state.state_dipole_moment
        adc[kind +
            "/transition_dipole_moments"] = state.transition_dipole_moment
        adc[kind + "/transition_dipole_moments_velocity"] = \
            state.transition_dipole_moment_velocity
        adc[kind + "/transition_magnetic_dipole_moments"] = \
            state.transition_magnetic_dipole_moment
        adc[kind + "/eigenvalues"] = state.excitation_energy
        adc[kind + "/eigenvectors_singles"] = np.asarray(eigenvectors_singles)

        if eigenvectors_doubles:  # For ADC(0) and ADC(1) there are no doubles
            adc.create_dataset(kind + "/eigenvectors_doubles",
                               compression=8,
                               data=np.asarray(eigenvectors_doubles))

    # Store which kinds are available
    out.create_dataset("available_kinds",
                       shape=(len(available_kinds), ),
                       data=np.array(available_kinds,
                                     dtype=h5py.special_dtype(vlen=str)))

    # TODO: dump state2state once in master
    return out
Пример #9
0
    def compute(self, input_model: "AtomicInput",
                config: "TaskConfig") -> "AtomicResult":
        """
        Runs adcc
        """
        self.found(raise_error=True)

        import adcc
        import psi4

        mol = input_model.molecule
        model = input_model.model
        conv_tol = input_model.keywords.get("conv_tol", 1e-6)

        if input_model.driver not in ["energy", "properties"]:
            raise InputError(
                f"Driver {input_model.driver} not implemented for ADCC.")

        if isinstance(input_model.model.basis, BasisSet):
            raise InputError(
                "QCSchema BasisSet for model.basis not implemented. Use string basis name."
            )
        if not input_model.model.basis:
            raise InputError("Model must contain a basis set.")

        psi4_molecule = psi4.core.Molecule.from_schema(
            dict(mol.dict(), fix_symmetry="c1"))
        psi4.core.clean()
        psi4.core.be_quiet()
        psi4.set_options({
            "basis":
            model.basis,
            "scf_type":
            "pk",
            "e_convergence":
            conv_tol / 100,
            "d_convergence":
            conv_tol / 10,
            # 'maxiter': max_iter,
            "reference":
            "RHF" if mol.molecular_multiplicity == 1 else "UHF",
        })
        _, wfn = psi4.energy("HF", return_wfn=True, molecule=psi4_molecule)
        adcc.set_n_threads(config.ncores)
        compute_success = False
        try:
            adcc_state = adcc.run_adc(wfn,
                                      method=model.method,
                                      **input_model.keywords)
            compute_success = adcc_state.converged
        except adcc.InputError as e:
            raise InputError(str(e))
        except Exception as e:
            raise UnknownError(str(e))

        input_data = input_model.dict(encoding="json")
        output_data = input_data.copy()
        output_data["success"] = compute_success

        if compute_success:
            output_data["return_result"] = adcc_state.excitation_energy[0]

            extract_props = input_model.driver == "properties"
            qcvars = adcc_state.to_qcvars(recurse=True,
                                          properties=extract_props)
            atprop = build_atomicproperties(qcvars)
            output_data["extras"]["qcvars"] = qcvars
            output_data["properties"] = atprop

        provenance = Provenance(creator="adcc",
                                version=self.get_version(),
                                routine="adcc").dict()
        provenance["nthreads"] = adcc.get_n_threads()
        output_data["provenance"] = provenance

        return AtomicResult(**output_data)
from relaxation import relax_cvs

# Run SCF in pyscf
mol = gto.M(atom="""
        O 0 0 0
        H 0 0 1.795239827225189
        H 1.693194615993441 0 -0.599043184453037
    """,
            basis='cc-pcvdz',
            unit="Bohr")
scfres = scf.RHF(mol)
scfres.conv_tol = 1e-12
scfres.conv_tol_grad = 1e-9
scfres.kernel()

# Run CVS-ADC(3) singles and relax to ADC(3) for O-edge
mat = AdcMatrix("cvs-adc3", ReferenceState(scfres, core_orbitals=1))
mats = AdcBlockView(mat, "s")
mats.method = mat.method
state = adcc.run_adc(mats, conv_tol=1e-8, n_singlets=10)
state_relaxed = relax_cvs(scfres, "adc3", state)

# Print results
print()
print(state.describe(oscillator_strengths=False))
print()
print()
print(state_relaxed.describe(oscillator_strengths=False))
print()
print("Residual norms: ", state_relaxed.residual_norms)
Пример #11
0
    O          7.98000        1.33100       -3.90100
    O          9.55600       -0.11000       -3.46600
    H          7.74900        2.71100        2.65200
    H          8.99100        1.57500        2.99500
    """,
    basis='sto-3g',
)

scfres = PE(scf.RHF(mol), {"potfile": "pna_6w.pot"})
scfres.conv_tol = 1e-8
scfres.conv_tol_grad = 1e-6
scfres.max_cycle = 250
scfres.kernel()

# model the solvent through perturbative corrections
state_pt = adcc.adc2(scfres,
                     n_singlets=5,
                     conv_tol=1e-5,
                     environment=['ptss', 'ptlr'])

# now model the solvent through linear-response coupling
# in the ADC matrix, re-using the matrix from previous run.
# This will modify state_pt.matrix
state_lr = adcc.run_adc(state_pt.matrix,
                        n_singlets=5,
                        conv_tol=1e-5,
                        environment='linear_response')

print(state_pt.describe())
print(state_lr.describe())