Skip to content

Commit

Permalink
nwchem working
Browse files Browse the repository at this point in the history
  • Loading branch information
loriab committed Nov 12, 2024
1 parent a7f030b commit 8bb0fee
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 36 deletions.
13 changes: 8 additions & 5 deletions qcengine/procedures/nwchem_opt/harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,21 @@ def harvest_as_atomic_result(input_model: OptimizationInput, nwout: str) -> List
provenance["module"] = module

# Format them inout an output
input_data = input_model.input_specification.model_dump()
input_data["driver"] = "gradient"
input_data["molecule"] = out_mol

output_data = {
"schema_version": 1,
"schema_version": 2,
"input_data": input_data,
"molecule": out_mol,
"driver": "gradient",
"extras": input_model.extras.copy(),
"model": input_model.input_specification.model,
"keywords": input_model.input_specification.keywords,
"extras": {},
"properties": atprop,
"provenance": provenance,
"return_result": nwgrad,
"success": True,
}
# v2: perhaps lost the OptimizationInput.extras?

# got to even out who needs plump/flat/Decimal/float/ndarray/list
# Decimal --> str preserves precision
Expand Down
4 changes: 2 additions & 2 deletions qcengine/programs/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ def build_input_model(
# Note: Someday when the multiple QCSchema versions QCEngine supports are all within the
# Pydantic v2 API base class, this can use discriminated unions instead of logic.

v1_model = getattr(qcelemental.models.v1, "AtomicInput")
v2_model = getattr(qcelemental.models.v2, "AtomicInput")
v1_model = qcelemental.models.v1.AtomicInput
v2_model = qcelemental.models.v2.AtomicInput

if isinstance(data, v1_model):
mdl = model_wrapper(data, v1_model)
Expand Down
7 changes: 4 additions & 3 deletions qcengine/programs/nwchem/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,10 @@ def parse_output(

# Format them inout an output
output_data = {
"schema_version": 1,
"schema_version": 2,
"input_data": input_model,
"molecule": nwmol, # overwrites with outfile Cartesians in case fix_*=F
"extras": {**input_model.extras},
"extras": {},
"native_files": {k: v for k, v in outfiles.items() if v is not None},
"properties": atprop,
"provenance": provenance,
Expand All @@ -343,4 +344,4 @@ def parse_output(
k.upper(): str(v) if isinstance(v, Decimal) else v for k, v in qcvars.items()
}

return AtomicResult(**{**input_model.model_dump(), **output_data})
return AtomicResult(**output_data)
2 changes: 1 addition & 1 deletion qcengine/programs/psi4.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pathlib import Path
from typing import TYPE_CHECKING, Any, ClassVar, Dict

from qcelemental.models.v1 import AtomicResult as AtomicResult
from qcelemental.models.v1 import AtomicResult
from qcelemental.models.v2 import BasisSet
from qcelemental.util import deserialize, parse_version, safe_version, which, which_import

Expand Down
9 changes: 9 additions & 0 deletions qcengine/programs/tests/standard_suite_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ def runner_asserter(inp, ref_subject, method, basis, tnm, scramble, frame, model
ref_block = mill_qcvars(ref2out_mill, ref_block)
ref_block_conv = mill_qcvars(ref2out_mill, ref_block_conv)

# 3b. input mol in output: `wfn.input_data.molecule` should be exactly `subject` always. If frame=free fails, check
# that the harness is copying AtomicInput bodily rather than duplicating AtomicResult.molecule as convert_v(2) does

if "v2" in tnm:
with np.printoptions(precision=3, suppress=True):
assert compare_values(
subject.geometry, wfn.input_data.molecule.geometry, atol=5.0e-8
), f"coords: atres ({wfn.input_data.molecule.geometry}) != atin ({subject.geometry})"

# <<< Comparison Tests >>>

assert wfn.success is True
Expand Down
5 changes: 4 additions & 1 deletion qcengine/programs/tests/test_ghost.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ def test_simple_ghost(driver, program, basis, keywords, hene_data, schema_versio
res = qcng.compute(resi, program, raise_error=True, return_dict=True, return_version=retver)
res = checkver_and_convert(res, request.node.name, "post")

assert res["driver"] == driver
if "v2" in request.node.name:
assert res["input_data"]["driver"] == driver
else:
assert res["driver"] == driver
assert "provenance" in res
assert res["success"] is True

Expand Down
15 changes: 12 additions & 3 deletions qcengine/programs/tests/test_nwchem.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ def test_b3lyp(nh2_data, schema_versions, request):

# Make sure the calculation completed successfully
assert compare_values(-55.554037, res["return_result"], atol=1e-3)
assert res["driver"] == "energy"
if "v2" in request.node.name:
assert res["input_data"]["driver"] == "energy"
else:
assert res["driver"] == "energy"
assert "provenance" in res
assert res["success"] is True

Expand Down Expand Up @@ -194,7 +197,10 @@ def test_dipole(h20_data, schema_versions, request):

# Make sure the calculation completed successfully
assert compare_values(-75.764944, res["return_result"], atol=1e-3)
assert res["driver"] == "properties"
if "v2" in request.node.name:
assert res["input_data"]["driver"] == "properties"
else:
assert res["driver"] == "properties"
assert "provenance" in res
assert res["success"] is True

Expand Down Expand Up @@ -244,7 +250,10 @@ def test_homo_lumo(h20v2_data, schema_versions, request):

# Make sure the calculation completed successfully
assert compare_values(-75.968095, res["return_result"], atol=1e-3)
assert res["driver"] == "energy"
if "v2" in request.node.name:
assert res["input_data"]["driver"] == "energy"
else:
assert res["driver"] == "energy"
assert "provenance" in res
assert res["success"] is True

Expand Down
10 changes: 8 additions & 2 deletions qcengine/programs/tests/test_standard_suite_ccsd(t).py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ def test_sp_ccsd_t_rhf_full(program, basis, keywords, h2o_data, schema_versions,
res = qcng.compute(resi, program, raise_error=True, return_dict=True, return_version=retver)
res = checkver_and_convert(res, request.node.name, "post")

assert res["driver"] == "energy"
if "v2" in request.node.name:
assert res["input_data"]["driver"] == "energy"
else:
assert res["driver"] == "energy"
assert "provenance" in res
assert res["success"] is True

Expand Down Expand Up @@ -122,7 +125,10 @@ def test_sp_ccsd_t_rohf_full(program, basis, keywords, nh2_data, schema_versions
res = checkver_and_convert(res, request.node.name, "post")
res = res.model_dump()

assert res["driver"] == "energy"
if "v2" in request.node.name:
assert res["input_data"]["driver"] == "energy"
else:
assert res["driver"] == "energy"
assert "provenance" in res
assert res["success"] is True

Expand Down
15 changes: 12 additions & 3 deletions qcengine/programs/tests/test_standard_suite_hf.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ def test_sp_hf_rhf(program, basis, keywords, h2o_data, schema_versions, request)
res = qcng.compute(resi, program, raise_error=True, return_dict=True, return_version=retver)
res = checkver_and_convert(res, request.node.name, "post")

assert res["driver"] == "energy"
if "v2" in request.node.name:
assert res["input_data"]["driver"] == "energy"
else:
assert res["driver"] == "energy"
assert "provenance" in res
assert res["success"] is True

Expand Down Expand Up @@ -119,7 +122,10 @@ def test_sp_hf_uhf(program, basis, keywords, nh2_data, schema_versions, request)

assert res.success is True
res = res.model_dump()
assert res["driver"] == "energy"
if "v2" in request.node.name:
assert res["input_data"]["driver"] == "energy"
else:
assert res["driver"] == "energy"
assert "provenance" in res
assert res["success"] is True

Expand Down Expand Up @@ -163,7 +169,10 @@ def test_sp_hf_rohf(program, basis, keywords, nh2_data, schema_versions, request
res = qcng.compute(resi, program, raise_error=True, return_dict=True, return_version=retver)
res = checkver_and_convert(res, request.node.name, "post")

assert res["driver"] == "energy"
if "v2" in request.node.name:
assert res["input_data"]["driver"] == "energy"
else:
assert res["driver"] == "energy"
assert "provenance" in res
assert res["success"] is True

Expand Down
22 changes: 6 additions & 16 deletions qcengine/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,19 +262,14 @@ def check_model_v2(m):

if prepost == "pre":
dict_in = isinstance(mdl, dict)
cast_smodel = cast_dict_as or "AtomicInput"
if "as_v1" in tnm or "to_v2" in tnm or "None" in tnm:
if dict_in:
if cast_dict_as:
mdl = getattr(qcel.models.v1, cast_dict_as)(**mdl)
else:
mdl = qcel.models.v1.AtomicInput(**mdl)
mdl = getattr(qcel.models.v1, cast_smodel)(**mdl)
check_model_v1(mdl)
elif "as_v2" in tnm or "to_v1" in tnm:
if dict_in:
if cast_dict_as:
mdl = getattr(qcel.models.v2, cast_dict_as)(**mdl)
else:
mdl = qcel.models.v2.AtomicInput(**mdl)
mdl = getattr(qcel.models.v2, cast_smodel)(**mdl)
check_model_v2(mdl)
# NOW IN COMPUTE mdl = mdl.convert_v(1)

Expand All @@ -286,19 +281,14 @@ def check_model_v2(m):
# for now these always go to v1 in programs/model.py so as_v2 returns wrongly as v1
# follow-up: there are too many ways this can happen, so now it's forestalled by the schema_versions fixture passing 2 to as_v2
dict_in = isinstance(mdl, dict)
cast_smodel = cast_dict_as or "AtomicResult"
if "as_v1" in tnm or "to_v1" in tnm or "None" in tnm:
if dict_in:
if cast_dict_as:
mdl = getattr(qcel.models.v1, cast_dict_as)(**mdl)
else:
mdl = qcel.models.v1.AtomicResult(**mdl)
mdl = getattr(qcel.models.v1, cast_smodel)(**mdl)
check_model_v1(mdl)
elif "as_v2" in tnm or "to_v2" in tnm:
if dict_in:
if cast_dict_as:
mdl = getattr(qcel.models.v2, cast_dict_as)(**mdl)
else:
mdl = qcel.models.v2.AtomicResult(**mdl)
mdl = getattr(qcel.models.v2, cast_smodel)(**mdl)
# NOW IN COMPUTE mdl = mdl.convert_v(2)
check_model_v2(mdl)

Expand Down
2 changes: 2 additions & 0 deletions qcengine/tests/test_harness_canonical.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
("mctc-gcp", {"method": "dft/sv"}, {}),
("mace", {"method": "small"}, {}),
("aimnet2", {"method": "b973c"}, {}),
("s-dftd3", {"method": "b3lyp-d3"}, {}),
("dftd4", {"method": "b3lyp-d4"}, {}),
# add as programs available
# ("terachem", {"method": "bad"}),
]
Expand Down

0 comments on commit 8bb0fee

Please sign in to comment.