Skip to content

Commit

Permalink
Merge branch 'master' into image_rfo
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexHeide authored Jul 2, 2024
2 parents 5560de1 + a2b46d7 commit 526120e
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 15 deletions.
20 changes: 17 additions & 3 deletions optking/compute_wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ def generate_schema_input(self, driver):

return inp

def generate_schema_input_for_procedure(self, driver):
molecule = Molecule(**self.molecule)
mbspec = self.keywords
mbspec["driver"] = driver

return {"molecule": molecule, "specification": mbspec}

def _compute(self, driver):
"""Abstract style method for child classes"""
pass
Expand Down Expand Up @@ -149,16 +156,23 @@ def _compute(self, driver):

import qcengine

inp = self.generate_schema_input(driver)

local_options = {}
if self.program == "psi4":
import psi4

local_options["memory"] = psi4.core.get_memory() / 1000000000
local_options["ncores"] = psi4.core.get_num_threads()

ret = qcengine.compute(inp, self.program, True, local_options)
if self.model == "(proc_spec_in_options)":
logger.debug("QCEngineComputer.path: ManyBody")
inp = self.generate_schema_input_for_procedure(driver)
ret = qcengine.compute_procedure(inp, "qcmanybody", True, local_options)

else:
logger.debug("QCEngineComputer.path: Atomic")
inp = self.generate_schema_input(driver)
ret = qcengine.compute(inp, self.program, True, local_options)

return ret


Expand Down
14 changes: 11 additions & 3 deletions optking/optwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,17 @@ def make_computer(opt_input: dict, computer_type):

# This gets updated so it shouldn't be a reference
molecule = copy.deepcopy(opt_input["initial_molecule"])
qc_input = opt_input["input_specification"]
options = qc_input["keywords"]
model = qc_input["model"]

# Sorting by spec_schema_name isn't foolproof b/c opt_input might not be a
# constructed model at this point if it's not arriving through QCEngine.
spec_schema_name = opt_input["input_specification"].get("schema_name", "qcschema_input")
if spec_schema_name == "qcschema_manybodyspecification":
model = "(proc_spec_in_options)"
options = opt_input["input_specification"]
else:
qc_input = opt_input["input_specification"]
options = qc_input["keywords"]
model = qc_input["model"]

if computer_type == "psi4":
# Please note that program is not actually used here
Expand Down
17 changes: 17 additions & 0 deletions optking/tests/json_lif_cp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{"initial_molecule": {"fragment_charges": [1, -1], "fragments": [[0], [1]], "geometry": [0.0, 0.0, 0.0, 0.0, 0.0, 3.0], "symbols": ["Li", "F"]},
"input_specification": {"driver": "energy",
"schema_name": "qcschema_manybodyspecification",
"keywords": {"bsse_type": "cp", "supersystem_ie_only": true},
"protocols": {"component_results": "all"},
"specification": {"driver": "energy",
"extras": {"psiapi": true},
"keywords": {},
"model": {"basis": "6-31g", "method": "hf"},
"program": "psi4",
"protocols": {"stdout": false}}},
"keywords": {"g_convergence": "interfrag_tight", "program": "psi4"},
"protocols": {"trajectory": "final"},
"provenance": {"creator": "optking", "routine": "optimize_qcengine", "version": "0.2.1+14.gdc8fd03.dirty"},
"schema_name": "qcschema_generalizedoptimizationinput",
"schema_version": 1}

17 changes: 17 additions & 0 deletions optking/tests/json_lif_nocp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{"initial_molecule": {"fragment_charges": [1, -1], "fragments": [[0], [1]], "geometry": [0.0, 0.0, 0.0, 0.0, 0.0, 3.0], "symbols": ["Li", "F"]},
"input_specification": {"driver": "energy",
"keywords": {"bsse_type": "nocp", "supersystem_ie_only": true},
"protocols": {"component_results": "all"},
"schema_name": "qcschema_manybodyspecification",
"specification": {"driver": "energy",
"extras": {"psiapi": true},
"keywords": {},
"model": {"basis": "6-31g", "method": "hf"},
"program": "psi4",
"protocols": {"stdout": false}}},
"keywords": {"g_convergence": "gau_verytight", "program": "psi4"},
"protocols": {"trajectory": "final"},
"provenance": {"creator": "optking", "routine": "optimize_qcengine", "version": "0.2.1+14.gdc8fd03.dirty"},
"schema_name": "qcschema_generalizedoptimizationinput",
"schema_version": 1}

5 changes: 5 additions & 0 deletions optking/tests/psi4_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import numpy
import pytest
from qcelemental.util import which_import

# Try to pull in Psi4
try:
Expand All @@ -15,3 +16,7 @@

# Wrap Psi4 in ifden
using_psi4 = pytest.mark.skipif(found_psi4, reason="Psi4 not found, skipping.")
using_qcmanybody = pytest.mark.skipif(
which_import("qcmanybody", return_bool=True) is False,
reason="cound not find qcmanybody. please install the package to enable tests",
)
40 changes: 31 additions & 9 deletions optking/tests/test_jsoninput.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,63 @@
import psi4

from qcelemental.models import OptimizationInput
from qcelemental.testing import compare_values
from .utils import utils
from .psi4_helper import using_qcmanybody

# Varying number of repulsion energy decimals to check.
@pytest.mark.parametrize(
"inp,expected,num_steps",
[
("json_h2o.json", (8.9064890670, -74.965901192, 3), 5),
("json_betapinene.json", (568.2219045869, -383.38105559, 1), 4),
("json_hooh_frozen.json", (37.969354880, -150.786372411, 2), 6),
pytest.param("json_h2o.json", (8.9064890670, -74.965901192, 3), 5),
pytest.param("json_betapinene.json", (568.2219045869, -383.38105559, 1), 4),
pytest.param("json_hooh_frozen.json", (37.969354880, -150.786372411, 2), 6),
pytest.param("json_lif_cp.json", (8.95167, -106.8867587, 2, 3.016), 4, marks=using_qcmanybody),
pytest.param("json_lif_nocp.json", (9.09281, -106.9208785, 2, 2.969), 5, marks=using_qcmanybody),
],
)
def test_input_through_json(inp, expected, num_steps, check_iter):
with open(os.path.join(os.path.dirname(__file__), inp)) as input_data:
input_copy = json.load(input_data)
opt_schema = OptimizationInput(**input_copy)
if "lif" in inp:
from qcmanybody.models.generalized_optimization import GeneralizedOptimizationInput
opt_schema = GeneralizedOptimizationInput(**input_copy)
else:
opt_schema = OptimizationInput(**input_copy)

# Note it's important to have `input_specification.schema_name = "qcschema_manybodyspecification"`
# in your json for a MBE optimization. Or you can explicitly construct a
# GeneralizedOptimizationInput like above.

# optking.run_json_file(os.path.join(os.path.dirname(__file__), inp))
json_dict = optking.optimize_qcengine(input_copy)

if "lif" in inp:
assert inp, json_dict["trajectory"][-1]["schema_name"] == "qcschema_manybodyresult"
else:
assert inp, json_dict["trajectory"][-1]["schema_name"] == "qcschema_output"

# For testing purposes. If this works, we have properly returned the output, and added the result
# to the original file. In order to preserve the form of the test suite, we now resore the input
# to its original state
# with open(os.path.join(os.path.dirname(__file__), inp)) as input_data:
# json_dict = json.load(input_data)
assert psi4.compare_values(

# LAB: for the MBE optimizations, psi4.compare_values strangely segfaults python, so using compare_values from qcel
assert compare_values(
expected[0],
json_dict["trajectory"][-1]["properties"]["nuclear_repulsion_energy"],
expected[2],
"Nuclear repulsion energy",
atol=1.0 * 10**-expected[2],
label="Nuclear repulsion energy",
)
assert psi4.compare_values(
expected[1], json_dict["trajectory"][-1]["properties"]["return_energy"], 6, "Reference energy"
assert compare_values(
expected[1], json_dict["trajectory"][-1]["properties"]["return_energy"], atol=1.e-6, label="Reference energy"
)
utils.compare_iterations(json_dict, num_steps, check_iter)

if len(expected) > 3:
assert compare_values(expected[3], json_dict["final_molecule"]["geometry"][5] - json_dict["final_molecule"]["geometry"][2], atol=1.e-3, label="bond length")

# with open(os.path.join(os.path.dirname(__file__), inp), 'r+') as input_data:
# input_data.seek(0)
# input_data.truncate()
Expand Down

0 comments on commit 526120e

Please sign in to comment.