Skip to content

Commit

Permalink
proper calculator (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
loriab authored Apr 28, 2024
1 parent b2ea3c6 commit 3f139a8
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- label: Py-max
python-version: "3.12"
runs-on: ubuntu-latest
pytest: "-k 'not (he4 and (3b or 4b))'"
pytest: "-k 'not (he4 and (3b or 4b) and not sio)'"

name: "🐍 ${{ matrix.cfg.python-version }} • ${{ matrix.cfg.label }} • ${{ matrix.cfg.runs-on }}"
runs-on: ${{ matrix.cfg.runs-on }}
Expand Down
32 changes: 17 additions & 15 deletions qcmanybody/qcng_computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def plan(self):
# v2: )
class Config:
extra = "allow"
frozen = False
# v2: frozen = False
allow_mutation = True


class AtomicComputerQCNG(BaseComputerQCNG):
Expand Down Expand Up @@ -155,8 +156,10 @@ class ManyBodyComputerQCNG(BaseComputerQCNG):
)
embedding_charges: Dict[int, List[float]] = Field(
{},
description="Atom-centered point charges to be used on molecule fragments whose basis sets are not included in "
"the computation. Keys: 1-based index of fragment. Values: list of atom charges for that fragment.",
description="Atom-centered point charges to be used to speed up nbody-level convergence. Charges are placed on "
"molecule fragments whose basis sets are not included in the computation. (An implication is that charges aren't "
"invoked for bsse_type=cp.) Keys: 1-based index of fragment. Values: list of atom charges for that fragment.",
# TODO: enforce point charge sum == fragment_charges val
json_schema_extra={
"shape": ["nfr", "<varies: nat in ifr>"],
},
Expand Down Expand Up @@ -190,7 +193,10 @@ class ManyBodyComputerQCNG(BaseComputerQCNG):
description=ManyBodyKeywords.__fields__["supersystem_ie_only"].field_info.description,
)
task_list: Dict[str, Any] = {} #MBETaskComputers] = {}
#qcmb_calculator: Optional[Any] = None
qcmb_calculator: Optional[Any] = Field(
None,
description="Low-level interface",
)

# TODO @computed_field(description="Number of distinct fragments comprising full molecular supersystem.")
@property
Expand All @@ -216,9 +222,10 @@ def set_bsse_type(cls, v: Any) -> List[BsseEnum]:
# v2: def set_embedding_charges(cls, v: Any, info: FieldValidationInfo) -> Dict[int, List[float]]:
def set_embedding_charges(cls, v, values): # -> Dict[int, List[float]]:
print(f"hit embedding_charges validator with {v}", end="")
nfr = len(values["molecule"].fragments)
# v2: if len(v) != info.data["nfragments"]:
if len(v) != len(values["molecule"].fragments):
raise ValueError(f"embedding_charges dict should have entries for each 1-indexed fragment ({len(values['molecule'].fragments)}).")
if len(v) != nfr:
raise ValueError(f"embedding_charges dict should have entries for each 1-indexed fragment ({nfr})")

print(f" ... setting embedding_charges={v}")
return v
Expand Down Expand Up @@ -396,7 +403,7 @@ def from_manybodyinput(cls, input_model: ManyBodyInput, build_tasks: bool = True
specifications[mtd]["specification"].pop("schema_name", None)
specifications[mtd]["specification"].pop("protocols", None)

calculator_cls = ManyBodyCalculator(
computer_model.qcmb_calculator = ManyBodyCalculator(
computer_model.molecule,
computer_model.bsse_type,
comp_levels,
Expand All @@ -406,11 +413,11 @@ def from_manybodyinput(cls, input_model: ManyBodyInput, build_tasks: bool = True
)

if not build_tasks:
return computer_model, calculator_cls
return computer_model

component_results = {}

for chem, label, imol in calculator_cls.iterate_molecules():
for chem, label, imol in computer_model.qcmb_calculator.iterate_molecules():
inp = AtomicInput(molecule=imol, **specifications[chem]["specification"])

if imol.extras.get("embedding_charges"): # or test on self.embedding_charges ?
Expand Down Expand Up @@ -445,7 +452,7 @@ def from_manybodyinput(cls, input_model: ManyBodyInput, build_tasks: bool = True
pprint.pprint(component_results, width=200)

print("start to analyze")
analyze_back = calculator_cls.analyze(component_results)
analyze_back = computer_model.qcmb_calculator.analyze(component_results)
analyze_back["nbody_number"] = len(component_results)
print("\n<<< (ZZ 3) QCEngine harness ManyBodyComputerQCNG.from_qcschema_ben analyze_back >>>")
pprint.pprint(analyze_back, width=200)
Expand All @@ -461,11 +468,6 @@ def compute(self, client: Optional["qcportal.FractalClient"] = None) -> None:
NOTE: client logic removed (compared to psi4.driver.ManyBodyComputer)
"""
# qcng: from psi4.driver.p4util import banner

# qcng: info = "\n" + banner(f" ManyBody Computations ", strNotOutfile=True) + "\n"
#logger.info(info)

for t in self.task_list.values():
t.compute(client=client)

Expand Down
3 changes: 2 additions & 1 deletion qcmanybody/tests/test_mbe_he4_multilevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,8 @@ def test_count_he4_multi(mbe_keywords, ref_count, he_tetramer, request):
atomic_spec = AtomicSpecification(model={"method": "mp2", "basis": "mybas"}, program="myqc", driver="energy")
mbe_model = ManyBodyInput(specification={"specification": atomic_spec, "keywords": mbe_keywords, "driver": "energy"}, molecule=he_tetramer)

_, ret = ManyBodyComputerQCNG.from_manybodyinput(mbe_model, build_tasks=False)
ret = ManyBodyComputerQCNG.from_manybodyinput(mbe_model, build_tasks=False)
ret = ret.qcmb_calculator

text, dcount = ret.format_calc_plan()
assert compare_recursive(ref_count["all"], dcount, atol=1.e-6)
Expand Down
3 changes: 2 additions & 1 deletion qcmanybody/tests/test_mbe_he4_singlelevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,8 @@ def test_count_he4_single(mbe_keywords, ref_count, he_tetramer):
atomic_spec = AtomicSpecification(model={"method": "mp2", "basis": "mybas"}, program="myqc", driver="energy")
mbe_model = ManyBodyInput(specification={"specification": atomic_spec, "keywords": mbe_keywords, "driver": "energy"}, molecule=he_tetramer)

_, ret = ManyBodyComputerQCNG.from_manybodyinput(mbe_model, build_tasks=False)
ret = ManyBodyComputerQCNG.from_manybodyinput(mbe_model, build_tasks=False)
ret = ret.qcmb_calculator

text, dcount = ret.format_calc_plan()
assert compare_recursive(ref_count["all"], dcount, atol=1.e-6)
Expand Down
10 changes: 5 additions & 5 deletions qcmanybody/tests/test_mbe_keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def test_mbe_rtd(mbe_data, driver, kws, ans):
mbe_data["specification"]["keywords"] = kws

input_model = ManyBodyInput(**mbe_data)
comp_model, _ = ManyBodyComputerQCNG.from_manybodyinput(input_model, build_tasks=False)
comp_model = ManyBodyComputerQCNG.from_manybodyinput(input_model, build_tasks=False)

assert comp_model.driver == driver
assert comp_model.return_total_data == ans
Expand Down Expand Up @@ -150,7 +150,7 @@ def test_mbe_level_bodies(mbe_data, kws, ans):
mbe_data["specification"]["keywords"] = kws

input_model = ManyBodyInput(**mbe_data)
comp_model, _ = ManyBodyComputerQCNG.from_manybodyinput(input_model, build_tasks=False)
comp_model = ManyBodyComputerQCNG.from_manybodyinput(input_model, build_tasks=False)

assert comp_model.nfragments == 3
assert comp_model.max_nbody == ans[0]
Expand Down Expand Up @@ -178,7 +178,7 @@ def test_mbe_level_5mer(mbe_data, kws, ans):
mbe_data["specification"]["keywords"] = kws

input_model = ManyBodyInput(**mbe_data)
comp_model, _ = ManyBodyComputerQCNG.from_manybodyinput(input_model, build_tasks=False)
comp_model = ManyBodyComputerQCNG.from_manybodyinput(input_model, build_tasks=False)

assert comp_model.nfragments == 5
assert comp_model.max_nbody == ans[0]
Expand Down Expand Up @@ -228,7 +228,7 @@ def test_mbe_bsse_type(mbe_data, kws, ans):
return

input_model = ManyBodyInput(**mbe_data)
comp_model, _ = ManyBodyComputerQCNG.from_manybodyinput(input_model, build_tasks=False)
comp_model = ManyBodyComputerQCNG.from_manybodyinput(input_model, build_tasks=False)

assert comp_model.bsse_type == ans, f"{comp_model=} != {ans}"

Expand Down Expand Up @@ -256,7 +256,7 @@ def test_mbe_sie(mbe_data, kws, ans):
return

input_model = ManyBodyInput(**mbe_data)
comp_model, _ = ManyBodyComputerQCNG.from_manybodyinput(input_model, build_tasks=False)
comp_model = ManyBodyComputerQCNG.from_manybodyinput(input_model, build_tasks=False)

assert comp_model.supersystem_ie_only == ans

Expand Down

0 comments on commit 3f139a8

Please sign in to comment.