Skip to content

Commit 2bbc72a

Browse files
committed
B5
1 parent 74fc4fa commit 2bbc72a

3 files changed

Lines changed: 49 additions & 37 deletions

File tree

arc/job/adapters/molpro.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
${cabs}
6161
int;
6262
63-
{hf;${shift}
63+
{${hf_method};${shift}
6464
maxit,999;
6565
wf,spin=${spin},charge=${charge};
6666
}
@@ -242,29 +242,36 @@ def write_input_file(self) -> None:
242242
input_dict['spin'] = self.multiplicity - 1
243243
input_dict['xyz'] = xyz_to_str(self.xyz)
244244
input_dict['orbitals'] = '\ngprint,orbitals;\n'
245+
input_dict['hf_method'] = 'hf' # default; overridden below for open-shell MRCC
245246

246247
if not is_restricted(self):
247248
input_dict['restricted'] = 'u'
248249

249250
if self.level.method in MRCC_ROUTED_METHODS:
250251
# Restriction is implicit from the preceding {hf;...} block; the
251252
# MRCC plugin call does not accept a 'u'/'r' prefix.
252-
mrcc_call = '{mrcc,method=' + self.level.method.upper() + '}'
253-
if not is_restricted(self):
254-
# Open-shell wavefunction: Molpro emits ROHF for the {hf;...}
255-
# block above. MRCC's approximate-CC family (CCSDT, CCSDT(Q),
256-
# CCSDTQ, CCSDTQ(P)) refuses standard ROHF orbitals with the
257-
# error "Approximate CC methods are not implemented for
258-
# standard ROHF orbitals! Use semicanonical orbitals!".
259-
# Running {uccsd} on the ROHF reference produces semicanonical
260-
# orbitals as a side effect; MRCC then picks them up
261-
# automatically. This costs one extra UCCSD pass per sub-job
262-
# but is the only way the post-(T) MRCC methods will run for
263-
# radicals. {ccsd} on its own would be cheaper but does not
264-
# consistently produce SC orbitals across Molpro versions.
265-
mrcc_call = '{uccsd}\n' + mrcc_call
266-
input_dict['method'] = mrcc_call
253+
input_dict['method'] = '{mrcc,method=' + self.level.method.upper() + '}'
267254
input_dict['restricted'] = ''
255+
if not is_restricted(self):
256+
# Open-shell wavefunction + MRCC's approximate-CC family
257+
# (CCSDT(Q), CCSDTQ(P), and the perturbative-(T) variants)
258+
# refuses standard ROHF orbitals:
259+
# "Approximate CC methods are not implemented for standard
260+
# ROHF orbitals! Use semicanonical orbitals!"
261+
# Solution: use UHF instead of (RO)HF as the SCF reference.
262+
# UHF orbitals are semicanonical by construction (alpha and
263+
# beta Fock matrices are separately diagonal) and live at the
264+
# default record 2100.2, which MRCC reads. MRCC then reports
265+
# ``Type=UHF/CANONICAL`` and accepts.
266+
#
267+
# An earlier attempt at this fix prepended ``{uccsd}`` to the
268+
# MRCC call. {uccsd} does run UCCSD on top of ROHF, but the
269+
# post-UCCSD canonical orbitals go to a separate record while
270+
# the default 2100.2 still holds the original ROHF orbitals —
271+
# MRCC reads 2100.2 by default and complained. Switching the
272+
# SCF reference to UHF avoids this orbital-record bookkeeping
273+
# entirely.
274+
input_dict['hf_method'] = 'uhf'
268275

269276
# Job type specific options
270277
if self.job_type in ['opt', 'optfreq', 'conf_opt']:

arc/job/adapters/molpro_test.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -462,26 +462,27 @@ def test_write_mrci_input_file(self):
462462
def test_write_input_file_mrcc_routing(self):
463463
"""Methods unsupported by native Molpro but supported by MRCC are routed through the MRCC plugin.
464464
465-
For an open-shell wavefunction, an additional ``{uccsd}`` step is
466-
emitted between the HF block and the MRCC plugin call. Molpro defaults
467-
to ROHF for open-shell HF, but MRCC's approximate-CC family
468-
(``CCSDT``, ``CCSDT(Q)``, ``CCSDTQ``, ``CCSDTQ(P)``) refuses standard
469-
ROHF orbitals with the error::
465+
For an open-shell wavefunction, the SCF reference is switched from
466+
``{hf;...}`` (which gives Molpro's ROHF for open-shell) to
467+
``{uhf;...}``. MRCC's approximate-CC family (``CCSDT(Q)``,
468+
``CCSDTQ(P)``, and the perturbative-``(T)`` variants) refuses
469+
standard ROHF orbitals with the error::
470470
471471
Approximate CC methods are not implemented for standard ROHF orbitals!
472472
Use semicanonical orbitals!
473473
474-
Running ``{uccsd}`` on the ROHF reference produces the semicanonical
475-
orbitals MRCC needs as a side effect — they're left on disk and the
476-
subsequent ``{mrcc,method=...}`` call picks them up automatically.
474+
UHF orbitals are semicanonical by construction (alpha and beta Fock
475+
matrices are separately diagonal), saved to the default record 2100.2
476+
which MRCC reads — MRCC then reports ``Type=UHF/CANONICAL`` and runs
477+
the requested approximate-CC method.
477478
"""
478479
self.job_mrcc_ccsdt.cpu_cores = 48
479480
self.job_mrcc_ccsdt.set_input_file_memory()
480481
self.job_mrcc_ccsdt.write_input_file()
481482
with open(os.path.join(self.job_mrcc_ccsdt.local_path,
482483
input_filenames[self.job_mrcc_ccsdt.job_adapter]), 'r') as f:
483484
content_ccsdt = f.read()
484-
# spc1 has multiplicity=3 (open-shell triplet) — uccsd prefix expected.
485+
# spc1 has multiplicity=3 (open-shell triplet) — UHF reference expected.
485486
expected_ccsdt = """***,spc1
486487
memory,Total=438,m;
487488
@@ -496,12 +497,11 @@ def test_write_input_file_mrcc_routing(self):
496497
497498
int;
498499
499-
{hf;
500+
{uhf;
500501
maxit,999;
501502
wf,spin=2,charge=0;
502503
}
503504
504-
{uccsd}
505505
{mrcc,method=CCSDT}
506506
507507
@@ -513,13 +513,12 @@ def test_write_input_file_mrcc_routing(self):
513513
# Sanity: the bare directive Molpro rejects must NOT appear on its own line.
514514
self.assertNotIn('\nccsdt;\n', content_ccsdt)
515515
self.assertNotIn('\nuccsdt;\n', content_ccsdt)
516-
# The uccsd step must come between the HF block and the mrcc plugin call —
517-
# not after, not before HF.
518-
uccsd_idx = content_ccsdt.index('{uccsd}')
519-
hf_close_idx = content_ccsdt.index('}\n\n{uccsd}')
520-
mrcc_idx = content_ccsdt.index('{mrcc,method=CCSDT}')
521-
self.assertLess(hf_close_idx, uccsd_idx)
522-
self.assertLess(uccsd_idx, mrcc_idx)
516+
# An earlier (insufficient) fix used `{uccsd}` between HF and MRCC —
517+
# this contract has been replaced with UHF, so {uccsd} must NOT appear.
518+
self.assertNotIn('{uccsd}', content_ccsdt)
519+
# UHF must replace HF as the only SCF reference (no {hf;...} block).
520+
self.assertNotIn('{hf;', content_ccsdt)
521+
self.assertIn('{uhf;', content_ccsdt)
523522

524523
self.job_mrcc_ccsdtq.cpu_cores = 48
525524
self.job_mrcc_ccsdtq.set_input_file_memory()
@@ -555,9 +554,11 @@ def test_write_input_file_mrcc_routing(self):
555554
"""
556555
self.assertEqual(content_ccsdtq, expected_ccsdtq)
557556
self.assertNotIn('\nccsdt(q);\n', content_ccsdtq)
558-
# spc1 here has multiplicity=1 (closed-shell) — no semicanonical-orbital
559-
# prep step is needed and none should be emitted.
557+
# spc1 here has multiplicity=1 (closed-shell) — RHF gives canonical
558+
# orbitals MRCC accepts directly. No UHF/UCCSD pre-step needed.
560559
self.assertNotIn('{uccsd}', content_ccsdtq)
560+
self.assertNotIn('{uhf;', content_ccsdtq)
561+
self.assertIn('{hf;', content_ccsdtq)
561562

562563
def test_set_files(self):
563564
"""Test setting files"""

arc/molecule/translator.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,11 @@ def _write(mol, identifier_type, backend):
553553
logger.warning(f"Unexpected error from backend '{option}': {e}")
554554
continue
555555

556-
logger.error(f"Unable to generate identifier '{identifier_type}' for this molecule:\n{mol.to_adjacency_list()}")
556+
logger.warning(
557+
f"Unable to generate identifier '{identifier_type}' for this molecule "
558+
f"(structure may be fragmented or carry anomalous formal charges):\n"
559+
f"{mol.to_adjacency_list()}"
560+
)
557561
raise ValueError(f"Unable to generate identifier type '{identifier_type}' with backend(s): {backend}")
558562

559563

0 commit comments

Comments
 (0)