Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add plain qcmanybody harness #466

Merged
merged 3 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions devtools/conda-envs/nwchem-cf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ dependencies:
- qcelemental >=0.24.0
- pydantic>=1.0.0
- networkx>=2.4.0
- qcmanybody

# Testing
- pytest
Expand Down
1 change: 1 addition & 0 deletions devtools/conda-envs/opt-disp-cf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies:
- geometric
- optking
- pymdi
- qcmanybody

# Core
- python
Expand Down
9 changes: 8 additions & 1 deletion docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,24 @@ Breaking Changes

New Features
++++++++++++
- (:pr:`466`) QCManyBody - new procedure for computing interaction energies or truncation or full
many-body expansions with no, counterpoise, or Valiron-Mayer function counterpoise correction
for basis set superposition error. @loriab

Enhancements
++++++++++++
- (:pr:`463`) Maint - Pin to QCElemental <0.70 since we now know QCSchema v2 release schedule.
- (:pr:`463`) MACE - New v0.3.9 release yields a pytorch error, so recommend pymace=0.3.6 .
- (:pr:`464`, :issue:`447`) CFOUR - Allow CC-PVDZ alias basis specification. Also fix the PwCVXZ
basis keyword. @philipmnel
- (:pr:`440`) TorsionDrive - Support other geometric-style constraints by not overwriting those
already present. @jthorton

Bug Fixes
+++++++++
- (:pr:`451`, :issue:`450`) Psi4 - Fixes bug in Psi4 detection when command `python` not available. @susilehtola, @topazus
- (:pr:`451`, :issue:`450`) Psi4 - Fixes bug in Psi4 detection when command `python` not available.
@susilehtola, @topazus
- (:pr:`466`) CFOUR - fix error collecting molecule when it's a single atom with two-letter symbol. @loriab

Misc.
+++++
Expand Down
2 changes: 2 additions & 0 deletions qcengine/procedures/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .geometric import GeometricProcedure
from .nwchem_opt import NWChemDriverProcedure
from .optking import OptKingProcedure
from .qcmanybody import QCManyBodyProcedure
from .torsiondrive import TorsionDriveProcedure
from .model import ProcedureHarness

Expand Down Expand Up @@ -69,5 +70,6 @@ def list_available_procedures() -> Set[str]:
register_procedure(GeometricProcedure())
register_procedure(OptKingProcedure())
register_procedure(BernyProcedure())
register_procedure(QCManyBodyProcedure())
register_procedure(NWChemDriverProcedure())
register_procedure(TorsionDriveProcedure())
51 changes: 51 additions & 0 deletions qcengine/procedures/qcmanybody.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from typing import TYPE_CHECKING, Any, Dict, Union

from qcelemental.util import safe_version, which_import

from .model import ProcedureHarness

if TYPE_CHECKING:
from ..config import TaskConfig
from qcmanybody.models import ManyBodyInput, ManyBodyResult


class QCManyBodyProcedure(ProcedureHarness):

# v2: ClassVar[Dict[str, Any]]
_defaults: Dict[str, Any] = {"name": "QCManyBody", "procedure": "manybody"}

version_cache: Dict[str, str] = {}

class Config(ProcedureHarness.Config):
pass

def found(self, raise_error: bool = False) -> bool:
return which_import(
"qcmanybody",
return_bool=True,
raise_error=raise_error,
raise_msg="Please install via `conda install qcmanybody -c conda-forge`.",
)

def build_input_model(self, data: Union[Dict[str, Any], "ManyBodyInput"]) -> "ManyBodyInput":
from qcmanybody.models import ManyBodyInput

return self._build_model(data, ManyBodyInput)

def get_version(self) -> str:
self.found(raise_error=True)

which_prog = which_import("qcmanybody")
if which_prog not in self.version_cache:
import qcmanybody

self.version_cache[which_prog] = safe_version(qcmanybody.__version__)

return self.version_cache[which_prog]

def compute(self, input_model: "ManyBodyInput", config: "TaskConfig") -> "ManyBodyResult":
from qcmanybody import ManyBodyComputer

output_model = ManyBodyComputer.from_manybodyinput(input_model)

return output_model
2 changes: 1 addition & 1 deletion qcengine/programs/adcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def found(raise_error: bool = False) -> bool:
"psi4",
return_bool=True,
raise_error=raise_error,
raise_msg="Please install psi4 for adcc harness via `conda install psi4 -c conda-forge/label/libint_dev -c conda-forge`.",
raise_msg="Please install psi4 for adcc harness via `conda install psi4 -c conda-forge`.",
)
return found_adcc and found_psi4

Expand Down
4 changes: 3 additions & 1 deletion qcengine/programs/cfour/harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,9 @@ def harvest_outfile_pass(outtext):
# Process atom geometry
mobj = re.search(r"^\s+" + r"@GETXYZ-I, 1 atoms read from ZMAT." + r"\s*$", outtext, re.MULTILINE)
mobj2 = re.search(
r"^([A-Z]+)#1" + r"\s+" + NUMBER + r"\s+" + NUMBER + r"\s+" + NUMBER + r"\s*$", outtext, re.MULTILINE
r"^\s*([A-Z]+)" + r"\s*" + r"#1" + r"\s+" + NUMBER + r"\s+" + NUMBER + r"\s+" + NUMBER + r"\s*$",
outtext,
re.MULTILINE,
)
if mobj and mobj2:
logger.debug("matched atom2") # unsavory for when atom never printed except for basis file
Expand Down
2 changes: 1 addition & 1 deletion qcengine/programs/psi4.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def found(raise_error: bool = False) -> bool:
"psi4",
return_bool=True,
raise_error=raise_error,
raise_msg="Please install via `conda install psi4 -c conda-forge/label/libint_dev -c conda-forge`. Check it's in your PATH with `which psi4`."
raise_msg="Please install via `conda install psi4 -c conda-forge`. Check it's in your PATH with `which psi4`."
+ error_msg,
)

Expand Down
12 changes: 9 additions & 3 deletions qcengine/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,14 @@ def is_program_new_enough(program, version_feature_introduced):
form is equal to or later than `version_feature_introduced`.

"""
if program not in qcng.list_available_programs():
return False
candidate_version = qcng.get_program(program).get_version()
if program in qcng.list_all_procedures():
if program not in qcng.list_available_procedures():
return False
candidate_version = qcng.get_procedure(program).get_version()
else:
if program not in qcng.list_available_programs():
return False
candidate_version = qcng.get_program(program).get_version()

return parse_version(candidate_version) >= parse_version(version_feature_introduced)

Expand Down Expand Up @@ -177,6 +182,7 @@ def get_job(self):
"psi4_derqcsk": is_program_new_enough("psi4", "1.5a1.dev117"),
"qcdb": which_import("qcdb", return_bool=True),
"qchem": is_program_new_enough("qchem", "5.1"),
"qcmanybody": which_import("qcmanybody", return_bool=True),
"rdkit": which_import("rdkit", return_bool=True),
"terachem": which("terachem", return_bool=True),
"terachem_pbs": is_program_new_enough("terachem_pbs", "0.7.2"),
Expand Down
Loading
Loading