-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #277 from maxscheurer/adcc-harness
Add adcc harness
- Loading branch information
Showing
9 changed files
with
223 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
name: test | ||
channels: | ||
- adcc | ||
- psi4/label/dev | ||
- conda-forge | ||
dependencies: | ||
- adcc>=0.15.7 | ||
- psi4 | ||
- blas=*=mkl # not needed but an example of disuading solver from openblas and old psi | ||
- intel-openmp!=2019.5 | ||
|
||
# Core | ||
- python | ||
- pyyaml | ||
- py-cpuinfo | ||
- psutil | ||
- qcelemental >=0.13.0 | ||
- pydantic>=1.0.0 | ||
- msgpack-python | ||
|
||
# Testing | ||
- pytest | ||
- pytest-cov | ||
- codecov | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
""" | ||
Calls adcc | ||
""" | ||
from typing import Dict, TYPE_CHECKING | ||
|
||
from qcelemental.util import safe_version, which_import | ||
from qcelemental.models import AtomicResult, Provenance | ||
from .qcvar_identities_resources import build_atomicproperties | ||
|
||
from .model import ProgramHarness | ||
from ..exceptions import InputError, UnknownError | ||
|
||
if TYPE_CHECKING: | ||
from qcelemental.models import AtomicInput | ||
|
||
from ..config import TaskConfig | ||
|
||
# | ||
|
||
|
||
class AdccHarness(ProgramHarness): | ||
_defaults = { | ||
"name": "adcc", | ||
"scratch": False, | ||
"thread_safe": False, | ||
"thread_parallel": True, | ||
"node_parallel": False, | ||
"managed_memory": True, | ||
} | ||
version_cache: Dict[str, str] = {} | ||
|
||
class Config(ProgramHarness.Config): | ||
pass | ||
|
||
@staticmethod | ||
def found(raise_error: bool = False) -> bool: | ||
"""Whether adcc harness is ready for operation. | ||
Parameters | ||
---------- | ||
raise_error: bool | ||
Passed on to control negative return between False and ModuleNotFoundError raised. | ||
Returns | ||
------- | ||
bool | ||
If adcc and psi4 are found, returns True. | ||
If raise_error is False and adcc or psi4 is missing, returns False. | ||
If raise_error is True and adcc or psi4 are missing, the error message is raised. | ||
""" | ||
found_adcc = which_import( | ||
"adcc", | ||
return_bool=True, | ||
raise_error=raise_error, | ||
raise_msg="Please install via `conda install adcc -c adcc`.", | ||
) | ||
found_psi4 = which_import( | ||
"psi4", | ||
return_bool=True, | ||
raise_error=raise_error, | ||
raise_msg="Please install psi4 for adcc harness via `conda install psi4 -c psi4`.", | ||
) | ||
return found_adcc and found_psi4 | ||
|
||
def get_version(self) -> str: | ||
"""Return the currently used version of adcc""" | ||
self.found(raise_error=True) | ||
|
||
which_prog = which_import("adcc") | ||
if which_prog not in self.version_cache: | ||
import adcc | ||
|
||
self.version_cache[which_prog] = safe_version(adcc.__version__) | ||
return self.version_cache[which_prog] | ||
|
||
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) | ||
|
||
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
"""Tests for adcc functionality""" | ||
import pytest | ||
import numpy as np | ||
import qcengine as qcng | ||
import qcelemental as qcel | ||
|
||
from qcengine.testing import using | ||
from qcelemental.testing import compare_values | ||
|
||
|
||
@pytest.fixture | ||
def h2o(): | ||
return qcel.models.Molecule.from_data( | ||
""" | ||
O 0.0 0.000 -0.129 | ||
H 0.0 -1.494 1.027 | ||
H 0.0 1.494 1.027 | ||
""" | ||
) | ||
|
||
|
||
@using("adcc") | ||
def test_run(h2o): | ||
inp = qcel.models.AtomicInput( | ||
molecule=h2o, driver="properties", model={"method": "adc2", "basis": "sto-3g"}, keywords={"n_singlets": 3} | ||
) | ||
ret = qcng.compute(inp, "adcc", raise_error=True, local_options={"ncores": 1}, return_dict=True) | ||
|
||
ref_excitations = np.array([0.0693704245883876, 0.09773854881340478, 0.21481589246935925]) | ||
ref_hf_energy = -74.45975898670224 | ||
ref_mp2_energy = -74.67111187456267 | ||
assert ret["success"] is True | ||
|
||
qcvars = ret["extras"]["qcvars"] | ||
|
||
assert qcvars["EXCITATION KIND"] == "SINGLET" | ||
assert compare_values(ref_excitations[0], ret["return_result"]) | ||
assert compare_values(ref_hf_energy, ret["properties"]["scf_total_energy"]) | ||
assert compare_values(ref_mp2_energy, ret["properties"]["mp2_total_energy"]) | ||
assert compare_values(ref_excitations, qcvars["ADC2 EXCITATION ENERGIES"]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters