Skip to content

Commit a55d031

Browse files
Added concerted xtb scans
1 parent 30bab85 commit a55d031

File tree

2 files changed

+105
-1
lines changed

2 files changed

+105
-1
lines changed

ccinput/packages/xtb.py

+19
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def __init__(self, calc):
3333
self.input_file = ""
3434
self.specifications = ""
3535
self.force_constant = 1.0
36+
self.concerted_scan = False
3637
self.confirmed_specifications = ""
3738

3839
if self.calc.type not in self.EXECUTABLES:
@@ -111,8 +112,17 @@ def handle_constraints_scan(self):
111112
if cmd.scan:
112113
self.has_scan = True
113114

115+
if self.concerted_scan and (
116+
not self.has_scan or len(self.calc.constraints) < 2
117+
):
118+
raise InvalidParameter(
119+
"The concerted mode only influences scans with multiple coordinates"
120+
)
121+
114122
if self.has_scan:
115123
self.input_file += "$scan\n"
124+
if self.concerted_scan:
125+
self.input_file += "mode=concerted\n"
116126
for counter, cmd in enumerate(self.calc.constraints):
117127
if cmd.scan:
118128
self.input_file += f"{counter+1}: {cmd.start_d:.2f}, {cmd.end_d:.2f}, {cmd.num_steps}\n"
@@ -217,6 +227,15 @@ def handle_specifications(self):
217227
self.cmd_arguments += "--squick "
218228
elif ss[0] == "mquick":
219229
self.cmd_arguments += "--mquick "
230+
elif ss[0] == "concerted":
231+
if self.calc.type not in [
232+
CalcType.CONSTR_OPT,
233+
]:
234+
raise InvalidParameter(
235+
f"Invalid specification for calculation type: {ss[0]}"
236+
)
237+
self.concerted_scan = True
238+
220239
else:
221240
raise InvalidParameter("Invalid specification")
222241
elif len(ss) == 2:

ccinput/tests/test_xtb.py

+86-1
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,56 @@ def test_scan_auto(self):
258258
"""
259259
self.assertTrue(self.is_equivalent(INPUT, xtb.input_file))
260260

261+
def test_scan_two_coordinates(self):
262+
params = {
263+
"type": "Constrained Optimisation",
264+
"file": "ethanol.xyz",
265+
"software": "xtb",
266+
"constraints": "Scan_9_1.4_10/1_2;Scan_9_1.4_10/2_3",
267+
}
268+
269+
xtb = self.generate_calculation(**params)
270+
271+
REF = "xtb ethanol.xyz --opt tight --input input"
272+
273+
self.assertTrue(self.is_equivalent(REF, xtb.command))
274+
275+
INPUT = """$constrain
276+
force constant=1.0
277+
distance: 1, 2, auto
278+
distance: 2, 3, auto
279+
$scan
280+
1: 9.00, 1.40, 10
281+
2: 9.00, 1.40, 10
282+
"""
283+
self.assertTrue(self.is_equivalent(INPUT, xtb.input_file))
284+
285+
def test_scan_two_coordinates_concerted(self):
286+
params = {
287+
"type": "Constrained Optimisation",
288+
"file": "ethanol.xyz",
289+
"software": "xtb",
290+
"constraints": "Scan_9_1.4_10/1_2;Scan_9_1.4_10/2_3",
291+
"specifications": "--concerted",
292+
}
293+
294+
xtb = self.generate_calculation(**params)
295+
296+
REF = "xtb ethanol.xyz --opt tight --input input"
297+
298+
self.assertTrue(self.is_equivalent(REF, xtb.command))
299+
300+
INPUT = """$constrain
301+
force constant=1.0
302+
distance: 1, 2, auto
303+
distance: 2, 3, auto
304+
$scan
305+
mode=concerted
306+
1: 9.00, 1.40, 10
307+
2: 9.00, 1.40, 10
308+
"""
309+
self.assertTrue(self.is_equivalent(INPUT, xtb.input_file))
310+
261311
def test_constrained_opt_no_constraint(self):
262312
params = {
263313
"type": "Constrained Optimisation",
@@ -266,7 +316,42 @@ def test_constrained_opt_no_constraint(self):
266316
}
267317

268318
with self.assertRaises(InvalidParameter):
269-
xtb = self.generate_calculation(**params)
319+
self.generate_calculation(**params)
320+
321+
def test_freeze_concerted_exception(self):
322+
params = {
323+
"type": "Constrained Optimisation",
324+
"file": "ethanol.xyz",
325+
"software": "xtb",
326+
"constraints": "Freeze_9_1.4_10;Freeze_9_1.4_10",
327+
"specifications": "--concerted",
328+
}
329+
330+
with self.assertRaises(InvalidParameter):
331+
self.generate_calculation(**params)
332+
333+
def test_scan_single_coordinate_concerted_exception(self):
334+
params = {
335+
"type": "Constrained Optimisation",
336+
"file": "ethanol.xyz",
337+
"software": "xtb",
338+
"constraints": "Scan_9_1.4_10/1_2;",
339+
"specifications": "--concerted",
340+
}
341+
342+
with self.assertRaises(InvalidParameter):
343+
self.generate_calculation(**params)
344+
345+
def test_opt_concerted_exception(self):
346+
params = {
347+
"type": "Geometrical Optimisation",
348+
"file": "ethanol.xyz",
349+
"software": "xtb",
350+
"specifications": "--concerted",
351+
}
352+
353+
with self.assertRaises(InvalidParameter):
354+
self.generate_calculation(**params)
270355

271356
def test_freeze(self):
272357
params = {

0 commit comments

Comments
 (0)