Skip to content

Commit cfae950

Browse files
committed
MRCC route in Molpro
1 parent b30e977 commit cfae950

2 files changed

Lines changed: 114 additions & 1 deletion

File tree

arc/job/adapters/molpro.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@
3434
settings['default_job_settings'], settings['global_ess_settings'], settings['input_filenames'], \
3535
settings['output_filenames'], settings['servers'], settings['submit_filenames']
3636

37+
# Methods that native Molpro does not support but its MRCC plugin does.
38+
# When the level's method matches one of these (case-insensitive), the adapter
39+
# emits a ``{mrcc,method=...}`` plugin call instead of a bare directive that
40+
# Molpro's input parser would reject with "Unknown command or directive".
41+
# Compared against the lowercased ``Level.method``.
42+
MRCC_ROUTED_METHODS = frozenset({
43+
'ccsdt',
44+
'ccsdt(q)',
45+
'ccsdtq',
46+
'ccsdtq(p)',
47+
'ccsdtqp',
48+
})
49+
50+
3751
input_template = """***,${label}
3852
memory,Total=${memory},m;
3953
@@ -232,6 +246,12 @@ def write_input_file(self) -> None:
232246
if not is_restricted(self):
233247
input_dict['restricted'] = 'u'
234248

249+
if self.level.method in MRCC_ROUTED_METHODS:
250+
# Restriction is implicit from the preceding {hf;...} block; the
251+
# MRCC plugin call does not accept a 'u'/'r' prefix.
252+
input_dict['method'] = '{mrcc,method=' + self.level.method.upper() + '}'
253+
input_dict['restricted'] = ''
254+
235255
# Job type specific options
236256
if self.job_type in ['opt', 'optfreq', 'conf_opt']:
237257
keywords = ['optg', 'root=2', 'method=qsd', 'readhess', "savexyz='geometry.xyz'"] if self.is_ts \

arc/job/adapters/molpro_test.py

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,24 @@ def setUpClass(cls):
9797
'closed': [1, 0, 0, 0, 0, 0, 0, 0]})],
9898
testing=True,
9999
)
100+
cls.job_mrcc_ccsdt = MolproAdapter(execution_type='queue',
101+
job_type='sp',
102+
level=Level(method='CCSDT', basis='cc-pVDZ'),
103+
project='test',
104+
project_directory=os.path.join(ARC_TESTING_PATH,
105+
'test_MolproAdapter_mrcc_ccsdt'),
106+
species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=3)],
107+
testing=True,
108+
)
109+
cls.job_mrcc_ccsdtq = MolproAdapter(execution_type='queue',
110+
job_type='sp',
111+
level=Level(method='CCSDT(Q)', basis='cc-pVDZ'),
112+
project='test',
113+
project_directory=os.path.join(ARC_TESTING_PATH,
114+
'test_MolproAdapter_mrcc_ccsdtq'),
115+
species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=1)],
116+
testing=True,
117+
)
100118

101119
def test_set_cpu_and_mem(self):
102120
"""Test assigning number of cpu's and memory"""
@@ -441,6 +459,80 @@ def test_write_mrci_input_file(self):
441459
"""
442460
self.assertEqual(content_7, job_7_expected_input_file)
443461

462+
def test_write_input_file_mrcc_routing(self):
463+
"""Methods unsupported by native Molpro but supported by MRCC are routed through the MRCC plugin."""
464+
self.job_mrcc_ccsdt.cpu_cores = 48
465+
self.job_mrcc_ccsdt.set_input_file_memory()
466+
self.job_mrcc_ccsdt.write_input_file()
467+
with open(os.path.join(self.job_mrcc_ccsdt.local_path,
468+
input_filenames[self.job_mrcc_ccsdt.job_adapter]), 'r') as f:
469+
content_ccsdt = f.read()
470+
expected_ccsdt = """***,spc1
471+
memory,Total=438,m;
472+
473+
geometry={angstrom;
474+
O 0.00000000 0.00000000 1.00000000}
475+
476+
gprint,orbitals;
477+
478+
basis=cc-pvdz
479+
480+
481+
482+
int;
483+
484+
{hf;
485+
maxit,999;
486+
wf,spin=2,charge=0;
487+
}
488+
489+
{mrcc,method=CCSDT}
490+
491+
492+
493+
---;
494+
495+
"""
496+
self.assertEqual(content_ccsdt, expected_ccsdt)
497+
# Sanity: the bare directive Molpro rejects must NOT appear on its own line.
498+
self.assertNotIn('\nccsdt;\n', content_ccsdt)
499+
self.assertNotIn('\nuccsdt;\n', content_ccsdt)
500+
501+
self.job_mrcc_ccsdtq.cpu_cores = 48
502+
self.job_mrcc_ccsdtq.set_input_file_memory()
503+
self.job_mrcc_ccsdtq.write_input_file()
504+
with open(os.path.join(self.job_mrcc_ccsdtq.local_path,
505+
input_filenames[self.job_mrcc_ccsdtq.job_adapter]), 'r') as f:
506+
content_ccsdtq = f.read()
507+
expected_ccsdtq = """***,spc1
508+
memory,Total=438,m;
509+
510+
geometry={angstrom;
511+
O 0.00000000 0.00000000 1.00000000}
512+
513+
gprint,orbitals;
514+
515+
basis=cc-pvdz
516+
517+
518+
519+
int;
520+
521+
{hf;
522+
maxit,999;
523+
wf,spin=0,charge=0;
524+
}
525+
526+
{mrcc,method=CCSDT(Q)}
527+
528+
529+
530+
---;
531+
532+
"""
533+
self.assertEqual(content_ccsdtq, expected_ccsdtq)
534+
self.assertNotIn('\nccsdt(q);\n', content_ccsdtq)
535+
444536
def test_set_files(self):
445537
"""Test setting files"""
446538
job_1_files_to_upload = [{'file_name': 'submit.sub',
@@ -468,7 +560,8 @@ def tearDownClass(cls):
468560
A function that is run ONCE after all unit tests in this class.
469561
Delete all project directories created during these unit tests
470562
"""
471-
for folder in ['test_MolproAdapter_1', 'test_MolproAdapter_2']:
563+
for folder in ['test_MolproAdapter_1', 'test_MolproAdapter_2',
564+
'test_MolproAdapter_mrcc_ccsdt', 'test_MolproAdapter_mrcc_ccsdtq']:
472565
shutil.rmtree(os.path.join(ARC_TESTING_PATH, folder), ignore_errors=True)
473566

474567

0 commit comments

Comments
 (0)