Skip to content

Commit 9a1ace4

Browse files
alongdclaude
andcommitted
orca: emit aux basis and CABS in a %basis block
The ! simple-input line accepts only the orbital basis; putting AuxC/CABS there is invalid ORCA syntax and broke DLPNO-CCSD(T)-F12 sp jobs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 365ca1d commit 9a1ace4

2 files changed

Lines changed: 41 additions & 14 deletions

File tree

arc/job/adapters/orca.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ def _format_orca_basis(basis: str) -> str:
9292
# job_options_keywords: input keywords that control the job
9393
# method_class: 'HF' for wavefunction methods (hf, mp, cc, dlpno ...). 'KS' for DFT methods.
9494
# options: additional keywords to control job (e.g., TightSCF, NormalPNO ...)
95-
input_template = """!${restricted}${method_class} ${method} ${basis} ${auxiliary_basis}${cabs} ${keywords}
96-
!${job_type_1}
97-
${job_type_2}
95+
input_template = """!${restricted}${method_class} ${method} ${basis} ${keywords}
96+
!${job_type_1}
97+
${job_type_2}${basis_block}
9898
%%maxcore ${memory}
9999
%%pal nprocs ${cpus} end
100100
@@ -270,9 +270,19 @@ def write_input_file(self) -> None:
270270
'keywords',
271271
]:
272272
input_dict[key] = ''
273-
input_dict['auxiliary_basis'] = _format_orca_basis(self.level.auxiliary_basis or '')
274273
input_dict['basis'] = _format_orca_basis(self.level.basis or '')
275-
input_dict['cabs'] = f' {_format_orca_basis(self.level.cabs)}' if self.level.cabs else ''
274+
# In ORCA, the orbital basis is the only basis allowed on the `!` simple-input line.
275+
# Auxiliary fitting bases (AuxC) and the F12 CABS must be declared inside a %basis block,
276+
# otherwise ORCA raises "UNRECOGNIZED OR DUPLICATED KEYWORD(S) IN SIMPLE INPUT LINE".
277+
basis_block_lines = []
278+
auxiliary_basis = _format_orca_basis(self.level.auxiliary_basis or '')
279+
if auxiliary_basis:
280+
basis_block_lines.append(f'AuxC "{auxiliary_basis}"')
281+
cabs = _format_orca_basis(self.level.cabs) if self.level.cabs else ''
282+
if cabs:
283+
basis_block_lines.append(f'CABS "{cabs}"')
284+
input_dict['basis_block'] = '\n%basis\n' + '\n'.join(basis_block_lines) + '\nend\n' \
285+
if basis_block_lines else ''
276286
input_dict['charge'] = self.charge
277287
input_dict['cpus'] = self.cpu_cores
278288
input_dict['label'] = self.species_label

arc/job/adapters/orca_test.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,12 @@ def test_write_input_file(self):
104104
self.job_1.write_input_file()
105105
with open(os.path.join(self.job_1.local_path, input_filenames[self.job_1.job_adapter]), 'r') as f:
106106
content_1 = f.read()
107-
job_1_expected_input_file = """!uHF dlpno-ccsd(t) def2-tzvp def2-tzvp/c tightscf normalpno
108-
!sp
107+
job_1_expected_input_file = """!uHF dlpno-ccsd(t) def2-tzvp tightscf normalpno
108+
!sp
109+
110+
%basis
111+
AuxC "def2-tzvp/c"
112+
end
109113
110114
%maxcore 1792
111115
%pal nprocs 8 end
@@ -130,8 +134,12 @@ def test_write_input_file_with_SMD_solvation(self):
130134
self.job_2.write_input_file()
131135
with open(os.path.join(self.job_2.local_path, input_filenames[self.job_2.job_adapter]), 'r') as f:
132136
content_2 = f.read()
133-
job_2_expected_input_file = """!uHF dlpno-ccsd(t) def2-tzvp def2-tzvp/c tightscf normalpno
134-
!sp
137+
job_2_expected_input_file = """!uHF dlpno-ccsd(t) def2-tzvp tightscf normalpno
138+
!sp
139+
140+
%basis
141+
AuxC "def2-tzvp/c"
142+
end
135143
136144
%maxcore 1792
137145
%pal nprocs 8 end
@@ -163,8 +171,12 @@ def test_write_input_file_with_CPCM_solvation(self):
163171
self.job_3.write_input_file()
164172
with open(os.path.join(self.job_3.local_path, input_filenames[self.job_3.job_adapter]), 'r') as f:
165173
content_3 = f.read()
166-
job_3_expected_input_file = """!uHF dlpno-ccsd(t) def2-tzvp def2-tzvp/c tightscf normalpno
167-
!sp
174+
job_3_expected_input_file = """!uHF dlpno-ccsd(t) def2-tzvp tightscf normalpno
175+
!sp
176+
177+
%basis
178+
AuxC "def2-tzvp/c"
179+
end
168180
169181
%maxcore 1792
170182
%pal nprocs 8 end
@@ -189,7 +201,7 @@ def test_write_input_file_with_CPCM_solvation(self):
189201
self.assertEqual(content_3, job_3_expected_input_file)
190202

191203
def test_write_input_file_f12_with_cabs(self):
192-
"""F12 sp_level with a cabs basis emits the CABS token on the ! line."""
204+
"""F12 sp_level with a cabs basis emits the AuxC and CABS tokens in a %basis block."""
193205
job_f12 = OrcaAdapter(execution_type='queue',
194206
job_type='sp',
195207
level=Level(method='DLPNO-CCSD(T)-F12',
@@ -208,8 +220,13 @@ def test_write_input_file_f12_with_cabs(self):
208220
bang_line = content.splitlines()[0]
209221
self.assertIn('dlpno-ccsd(t)-f12', bang_line)
210222
self.assertIn('cc-pvtz-f12', bang_line)
211-
self.assertIn('aug-cc-pvtz/c', bang_line)
212-
self.assertIn('cc-pvtz-f12-cabs', bang_line)
223+
# Aux and CABS must NOT be on the ! line (ORCA rejects them there), only the orbital basis.
224+
self.assertNotIn('aug-cc-pvtz/c', bang_line)
225+
self.assertNotIn('cabs', bang_line.lower())
226+
# They must appear inside a %basis block instead.
227+
self.assertIn('%basis', content)
228+
self.assertIn('AuxC "aug-cc-pvtz/c"', content)
229+
self.assertIn('CABS "cc-pvtz-f12-cabs"', content)
213230

214231
def test_write_input_file_f12_without_cabs_raises(self):
215232
"""F12 sp_level without a cabs basis raises at input-file generation."""

0 commit comments

Comments
 (0)