Skip to content
8 changes: 5 additions & 3 deletions arc/job/adapters/orca.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
An adapter for executing Orca 5 jobs
An adapter for executing Orca 5/6 jobs

https://orcaforum.kofo.mpg.de/app.php/portal
"""
Expand Down Expand Up @@ -291,9 +291,10 @@ def write_input_file(self) -> None:
# Orca requires different blocks for wavefunction methods and DFT methods
if self.level.method_type == 'dft':
input_dict['method_class'] = 'KS'
# DFT grid must be the same for both opt and freq.
# Use a consistent DFT grid for fine_opt jobs and for any job with a frequency calculation
# (`freq` and `optfreq`), so `optfreq` is treated like `freq` here and defaults to `defgrid3`.
# Users can override by setting `dft_grid` in args.keyword (e.g. dft_grid: DEFGRID1).
self.args['keyword'].setdefault('dft_grid', 'defgrid3' if self.fine else 'defgrid2')
self.args['keyword'].setdefault('dft_grid', 'defgrid3' if self.fine or self.job_type in ['freq', 'optfreq'] else 'defgrid2')
elif self.level.method_type == 'wavefunction':
input_dict['method_class'] = 'HF'
if 'dlpno' in self.level.method:
Expand Down Expand Up @@ -325,6 +326,7 @@ def write_input_file(self) -> None:
self.add_to_args(val="""
%geom
Calc_Hess true # calculation of the exact Hessian before the first opt step
Recalc_Hess 5
end
""",
key1='block')
Expand Down
161 changes: 161 additions & 0 deletions arc/job/adapters/orca_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,167 @@ def test_set_files(self):
self.assertEqual(self.job_1.files_to_upload, job_1_files_to_upload)
self.assertEqual(self.job_1.files_to_download, job_1_files_to_download)

def test_dft_grid_regular_opt(self):
"""Test that regular opt job uses defgrid2 for DFT"""
job_opt = OrcaAdapter(execution_type='queue',
job_type='opt',
level=Level(method='wb97x-d3', basis='def2-tzvp'),
project='test_dft_grid',
project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'),
species=[ARCSpecies(label='CH3O',
xyz="""C 0.03807240 0.00035621 -0.00484242
O 1.35198769 0.01264937 -0.17195885
H -0.33965241 -0.14992727 1.02079480
H -0.51702680 0.90828035 -0.29592912
H -0.53338088 -0.77135867 -0.54806440""")],
testing=True,
fine=False,
)
job_opt.write_input_file()
with open(os.path.join(job_opt.local_path, input_filenames[job_opt.job_adapter]), 'r') as f:
content = f.read()
self.assertIn('defgrid2', content)
self.assertNotIn('defgrid3', content)

def test_dft_grid_fine_opt(self):
"""Test that fine opt job uses defgrid3 for DFT"""
job_fine_opt = OrcaAdapter(execution_type='queue',
job_type='opt',
level=Level(method='wb97x-d3', basis='def2-tzvp'),
project='test_dft_grid_fine',
project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'),
species=[ARCSpecies(label='CH3O',
xyz="""C 0.03807240 0.00035621 -0.00484242
O 1.35198769 0.01264937 -0.17195885
H -0.33965241 -0.14992727 1.02079480
H -0.51702680 0.90828035 -0.29592912
H -0.53338088 -0.77135867 -0.54806440""")],
testing=True,
fine=True,
)
job_fine_opt.write_input_file()
with open(os.path.join(job_fine_opt.local_path, input_filenames[job_fine_opt.job_adapter]), 'r') as f:
content = f.read()
self.assertIn('defgrid3', content)

def test_dft_grid_freq(self):
"""Test that freq job uses defgrid3 for DFT"""
job_freq = OrcaAdapter(execution_type='queue',
job_type='freq',
level=Level(method='wb97x-d3', basis='def2-tzvp'),
project='test_dft_grid_freq',
project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'),
species=[ARCSpecies(label='CH3O',
xyz="""C 0.03807240 0.00035621 -0.00484242
O 1.35198769 0.01264937 -0.17195885
H -0.33965241 -0.14992727 1.02079480
H -0.51702680 0.90828035 -0.29592912
H -0.53338088 -0.77135867 -0.54806440""")],
testing=True,
fine=False,
)
job_freq.write_input_file()
with open(os.path.join(job_freq.local_path, input_filenames[job_freq.job_adapter]), 'r') as f:
content = f.read()
self.assertIn('defgrid3', content)

def test_dft_grid_optfreq(self):
"""Test that optfreq job uses defgrid3 for DFT"""
job_optfreq = OrcaAdapter(execution_type='queue',
job_type='optfreq',
level=Level(method='wb97x-d3', basis='def2-tzvp'),
project='test_dft_grid_optfreq',
project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'),
species=[ARCSpecies(label='CH3O',
xyz="""C 0.03807240 0.00035621 -0.00484242
O 1.35198769 0.01264937 -0.17195885
H -0.33965241 -0.14992727 1.02079480
H -0.51702680 0.90828035 -0.29592912
H -0.53338088 -0.77135867 -0.54806440""")],
testing=True,
fine=False,
)
job_optfreq.write_input_file()
with open(os.path.join(job_optfreq.local_path, input_filenames[job_optfreq.job_adapter]), 'r') as f:
content = f.read()
self.assertIn('defgrid3', content)

def test_fine_opt_convergence_tightopt(self):
"""Test that fine opt job uses TightOpt convergence for DFT"""
job_fine_opt = OrcaAdapter(execution_type='queue',
job_type='opt',
level=Level(method='wb97x-d3', basis='def2-tzvp'),
project='test_fine_opt_conv',
project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'),
species=[ARCSpecies(label='CH3O',
xyz="""C 0.03807240 0.00035621 -0.00484242
O 1.35198769 0.01264937 -0.17195885
H -0.33965241 -0.14992727 1.02079480
H -0.51702680 0.90828035 -0.29592912
H -0.53338088 -0.77135867 -0.54806440""")],
testing=True,
fine=True,
)
job_fine_opt.write_input_file()
with open(os.path.join(job_fine_opt.local_path, input_filenames[job_fine_opt.job_adapter]), 'r') as f:
content = f.read()
# TightOpt should be present in fine opt
self.assertIn('tightopt', content.lower())

def test_recalc_hess_in_optts(self):
"""Test that OptTS job includes Recalc_Hess 5 in %geom block"""
job_optts = OrcaAdapter(execution_type='queue',
job_type='opt',
level=Level(method='wb97x-d3', basis='def2-tzvp'),
project='test_optts_hess',
project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'),
species=[ARCSpecies(label='TS_example',
xyz="""C 0.03807240 0.00035621 -0.00484242
O 1.35198769 0.01264937 -0.17195885
H -0.33965241 -0.14992727 1.02079480
H -0.51702680 0.90828035 -0.29592912
H -0.53338088 -0.77135867 -0.54806440""",
is_ts=True)],
testing=True,
fine=False,
)
job_optts.write_input_file()
with open(os.path.join(job_optts.local_path, input_filenames[job_optts.job_adapter]), 'r') as f:
content = f.read()
# Check that the file contains the %geom block with Calc_Hess and Recalc_Hess
self.assertIn('%geom', content)
self.assertIn('Calc_Hess true', content)
self.assertIn('Recalc_Hess 5', content)
# Check that it's an OptTS job
self.assertIn('OptTS', content)

def test_recalc_hess_not_in_regular_opt(self):
"""Test that regular Opt job (non-TS) does NOT include Recalc_Hess block"""
job_opt_regular = OrcaAdapter(execution_type='queue',
job_type='opt',
level=Level(method='wb97x-d3', basis='def2-tzvp'),
project='test_opt_no_hess',
project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'),
species=[ARCSpecies(label='CH3O',
xyz="""C 0.03807240 0.00035621 -0.00484242
O 1.35198769 0.01264937 -0.17195885
H -0.33965241 -0.14992727 1.02079480
H -0.51702680 0.90828035 -0.29592912
H -0.53338088 -0.77135867 -0.54806440""",
is_ts=False)],
testing=True,
fine=False,
)
job_opt_regular.write_input_file()
with open(os.path.join(job_opt_regular.local_path, input_filenames[job_opt_regular.job_adapter]), 'r') as f:
content = f.read()
# Check that it's a regular Opt job, not OptTS
self.assertIn('!Opt', content)
self.assertNotIn('OptTS', content)
# The %geom Calc_Hess block should NOT be present for regular opt
self.assertNotIn('Calc_Hess true', content)
self.assertNotIn('Recalc_Hess 5', content)

@classmethod
def tearDownClass(cls):
"""
Expand Down