1#![allow(clippy::approx_constant)]
7
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct XtbParams {
13 pub z: u8,
15 pub symbol: &'static str,
17 pub n_valence: u8,
19 pub h_s: f64,
21 pub h_p: f64,
23 pub h_d: f64,
25 pub zeta_s: f64,
27 pub zeta_p: f64,
29 pub zeta_d: f64,
31 pub eta: f64,
33 pub en: f64,
35 pub r_cov: f64,
37 pub cn_ref: f64,
39}
40
41static XTB_PARAMS: &[(u8, XtbParams)] = &[
45 (
46 1,
47 XtbParams {
48 z: 1,
49 symbol: "H",
50 n_valence: 1,
51 h_s: -10.707,
52 h_p: 0.0,
53 h_d: 0.0,
54 zeta_s: 1.230,
55 zeta_p: 0.0,
56 zeta_d: 0.0,
57 eta: 7.461,
58 en: 2.20,
59 r_cov: 0.32,
60 cn_ref: 1.0,
61 },
62 ),
63 (
64 5,
65 XtbParams {
66 z: 5,
67 symbol: "B",
68 n_valence: 3,
69 h_s: -13.170,
70 h_p: -6.480,
71 h_d: 0.0,
72 zeta_s: 1.596,
73 zeta_p: 1.307,
74 zeta_d: 0.0,
75 eta: 4.010,
76 en: 2.04,
77 r_cov: 0.85,
78 cn_ref: 3.0,
79 },
80 ),
81 (
82 6,
83 XtbParams {
84 z: 6,
85 symbol: "C",
86 n_valence: 4,
87 h_s: -13.970,
88 h_p: -5.195,
89 h_d: 0.0,
90 zeta_s: 1.739,
91 zeta_p: 1.419,
92 zeta_d: 0.0,
93 eta: 5.343,
94 en: 2.55,
95 r_cov: 0.77,
96 cn_ref: 3.0,
97 },
98 ),
99 (
100 7,
101 XtbParams {
102 z: 7,
103 symbol: "N",
104 n_valence: 5,
105 h_s: -14.120,
106 h_p: -5.320,
107 h_d: 0.0,
108 zeta_s: 1.950,
109 zeta_p: 1.590,
110 zeta_d: 0.0,
111 eta: 6.899,
112 en: 3.04,
113 r_cov: 0.71,
114 cn_ref: 3.0,
115 },
116 ),
117 (
118 8,
119 XtbParams {
120 z: 8,
121 symbol: "O",
122 n_valence: 6,
123 h_s: -17.280,
124 h_p: -8.590,
125 h_d: 0.0,
126 zeta_s: 2.227,
127 zeta_p: 1.856,
128 zeta_d: 0.0,
129 eta: 8.210,
130 en: 3.44,
131 r_cov: 0.66,
132 cn_ref: 2.0,
133 },
134 ),
135 (
136 9,
137 XtbParams {
138 z: 9,
139 symbol: "F",
140 n_valence: 7,
141 h_s: -20.010,
142 h_p: -11.470,
143 h_d: 0.0,
144 zeta_s: 2.490,
145 zeta_p: 2.100,
146 zeta_d: 0.0,
147 eta: 10.874,
148 en: 3.98,
149 r_cov: 0.64,
150 cn_ref: 1.0,
151 },
152 ),
153 (
154 14,
155 XtbParams {
156 z: 14,
157 symbol: "Si",
158 n_valence: 4,
159 h_s: -10.320,
160 h_p: -4.105,
161 h_d: 0.0,
162 zeta_s: 1.634,
163 zeta_p: 1.288,
164 zeta_d: 0.0,
165 eta: 3.380,
166 en: 1.90,
167 r_cov: 1.17,
168 cn_ref: 4.0,
169 },
170 ),
171 (
172 15,
173 XtbParams {
174 z: 15,
175 symbol: "P",
176 n_valence: 5,
177 h_s: -12.550,
178 h_p: -5.060,
179 h_d: 0.0,
180 zeta_s: 1.880,
181 zeta_p: 1.490,
182 zeta_d: 0.0,
183 eta: 4.880,
184 en: 2.19,
185 r_cov: 1.10,
186 cn_ref: 3.0,
187 },
188 ),
189 (
190 16,
191 XtbParams {
192 z: 16,
193 symbol: "S",
194 n_valence: 6,
195 h_s: -13.300,
196 h_p: -6.890,
197 h_d: 0.0,
198 zeta_s: 2.020,
199 zeta_p: 1.670,
200 zeta_d: 0.0,
201 eta: 4.563,
202 en: 2.58,
203 r_cov: 1.04,
204 cn_ref: 2.0,
205 },
206 ),
207 (
208 17,
209 XtbParams {
210 z: 17,
211 symbol: "Cl",
212 n_valence: 7,
213 h_s: -15.030,
214 h_p: -8.110,
215 h_d: 0.0,
216 zeta_s: 2.180,
217 zeta_p: 1.850,
218 zeta_d: 0.0,
219 eta: 5.852,
220 en: 3.16,
221 r_cov: 0.99,
222 cn_ref: 1.0,
223 },
224 ),
225 (
226 35,
227 XtbParams {
228 z: 35,
229 symbol: "Br",
230 n_valence: 7,
231 h_s: -13.100,
232 h_p: -7.380,
233 h_d: 0.0,
234 zeta_s: 2.440,
235 zeta_p: 2.010,
236 zeta_d: 0.0,
237 eta: 5.012,
238 en: 2.96,
239 r_cov: 1.14,
240 cn_ref: 1.0,
241 },
242 ),
243 (
244 53,
245 XtbParams {
246 z: 53,
247 symbol: "I",
248 n_valence: 7,
249 h_s: -11.480,
250 h_p: -6.250,
251 h_d: 0.0,
252 zeta_s: 2.680,
253 zeta_p: 2.190,
254 zeta_d: 0.0,
255 eta: 4.180,
256 en: 2.66,
257 r_cov: 1.33,
258 cn_ref: 1.0,
259 },
260 ),
261 (
263 22,
264 XtbParams {
265 z: 22,
266 symbol: "Ti",
267 n_valence: 4,
268 h_s: -8.970,
269 h_p: -5.440,
270 h_d: -10.810,
271 zeta_s: 1.075,
272 zeta_p: 1.075,
273 zeta_d: 4.550,
274 eta: 3.400,
275 en: 1.54,
276 r_cov: 1.36,
277 cn_ref: 6.0,
278 },
279 ),
280 (
281 24,
282 XtbParams {
283 z: 24,
284 symbol: "Cr",
285 n_valence: 6,
286 h_s: -8.660,
287 h_p: -5.240,
288 h_d: -11.220,
289 zeta_s: 1.700,
290 zeta_p: 1.700,
291 zeta_d: 4.950,
292 eta: 3.720,
293 en: 1.66,
294 r_cov: 1.27,
295 cn_ref: 6.0,
296 },
297 ),
298 (
299 25,
300 XtbParams {
301 z: 25,
302 symbol: "Mn",
303 n_valence: 7,
304 h_s: -9.750,
305 h_p: -5.890,
306 h_d: -11.670,
307 zeta_s: 1.800,
308 zeta_p: 1.800,
309 zeta_d: 5.150,
310 eta: 3.720,
311 en: 1.55,
312 r_cov: 1.39,
313 cn_ref: 6.0,
314 },
315 ),
316 (
317 26,
318 XtbParams {
319 z: 26,
320 symbol: "Fe",
321 n_valence: 8,
322 h_s: -9.100,
323 h_p: -5.320,
324 h_d: -12.600,
325 zeta_s: 1.900,
326 zeta_p: 1.900,
327 zeta_d: 5.350,
328 eta: 3.960,
329 en: 1.83,
330 r_cov: 1.25,
331 cn_ref: 6.0,
332 },
333 ),
334 (
335 27,
336 XtbParams {
337 z: 27,
338 symbol: "Co",
339 n_valence: 9,
340 h_s: -9.210,
341 h_p: -5.290,
342 h_d: -13.180,
343 zeta_s: 2.000,
344 zeta_p: 2.000,
345 zeta_d: 5.550,
346 eta: 4.105,
347 en: 1.88,
348 r_cov: 1.26,
349 cn_ref: 6.0,
350 },
351 ),
352 (
353 28,
354 XtbParams {
355 z: 28,
356 symbol: "Ni",
357 n_valence: 10,
358 h_s: -10.950,
359 h_p: -6.270,
360 h_d: -13.490,
361 zeta_s: 2.100,
362 zeta_p: 2.100,
363 zeta_d: 5.750,
364 eta: 4.295,
365 en: 1.91,
366 r_cov: 1.21,
367 cn_ref: 4.0,
368 },
369 ),
370 (
371 29,
372 XtbParams {
373 z: 29,
374 symbol: "Cu",
375 n_valence: 11,
376 h_s: -11.400,
377 h_p: -6.060,
378 h_d: -14.000,
379 zeta_s: 2.200,
380 zeta_p: 2.200,
381 zeta_d: 5.950,
382 eta: 4.200,
383 en: 1.90,
384 r_cov: 1.38,
385 cn_ref: 4.0,
386 },
387 ),
388 (
389 30,
390 XtbParams {
391 z: 30,
392 symbol: "Zn",
393 n_valence: 12,
394 h_s: -12.410,
395 h_p: -6.530,
396 h_d: -17.990,
397 zeta_s: 2.010,
398 zeta_p: 2.010,
399 zeta_d: 6.150,
400 eta: 4.870,
401 en: 1.65,
402 r_cov: 1.31,
403 cn_ref: 4.0,
404 },
405 ),
406 (
408 44,
409 XtbParams {
410 z: 44,
411 symbol: "Ru",
412 n_valence: 8,
413 h_s: -10.400,
414 h_p: -6.870,
415 h_d: -14.900,
416 zeta_s: 1.900,
417 zeta_p: 1.900,
418 zeta_d: 5.380,
419 eta: 3.500,
420 en: 2.20,
421 r_cov: 1.26,
422 cn_ref: 6.0,
423 },
424 ),
425 (
426 46,
427 XtbParams {
428 z: 46,
429 symbol: "Pd",
430 n_valence: 10,
431 h_s: -7.320,
432 h_p: -3.750,
433 h_d: -12.020,
434 zeta_s: 2.190,
435 zeta_p: 2.190,
436 zeta_d: 5.983,
437 eta: 3.890,
438 en: 2.20,
439 r_cov: 1.31,
440 cn_ref: 4.0,
441 },
442 ),
443 (
444 47,
445 XtbParams {
446 z: 47,
447 symbol: "Ag",
448 n_valence: 11,
449 h_s: -6.270,
450 h_p: -3.970,
451 h_d: -14.580,
452 zeta_s: 2.242,
453 zeta_p: 2.242,
454 zeta_d: 6.070,
455 eta: 3.140,
456 en: 1.93,
457 r_cov: 1.53,
458 cn_ref: 4.0,
459 },
460 ),
461 (
463 78,
464 XtbParams {
465 z: 78,
466 symbol: "Pt",
467 n_valence: 10,
468 h_s: -9.077,
469 h_p: -5.475,
470 h_d: -12.590,
471 zeta_s: 2.550,
472 zeta_p: 2.550,
473 zeta_d: 6.013,
474 eta: 4.360,
475 en: 2.28,
476 r_cov: 1.28,
477 cn_ref: 4.0,
478 },
479 ),
480 (
481 79,
482 XtbParams {
483 z: 79,
484 symbol: "Au",
485 n_valence: 11,
486 h_s: -10.920,
487 h_p: -5.550,
488 h_d: -15.070,
489 zeta_s: 2.600,
490 zeta_p: 2.600,
491 zeta_d: 6.163,
492 eta: 5.010,
493 en: 2.54,
494 r_cov: 1.44,
495 cn_ref: 4.0,
496 },
497 ),
498];
499
500pub fn get_xtb_params(z: u8) -> Option<&'static XtbParams> {
502 XTB_PARAMS
503 .iter()
504 .find(|(elem, _)| *elem == z)
505 .map(|(_, p)| p)
506}
507
508pub fn is_xtb_supported(z: u8) -> bool {
510 get_xtb_params(z).is_some()
511}
512
513pub fn count_xtb_electrons(elements: &[u8]) -> usize {
515 elements
516 .iter()
517 .map(|&z| get_xtb_params(z).map_or(0, |p| p.n_valence as usize))
518 .sum()
519}
520
521pub fn num_xtb_basis_functions(z: u8) -> usize {
523 match get_xtb_params(z) {
524 None => 0,
525 Some(p) => {
526 let mut n = 1; if p.zeta_p > 0.0 {
528 n += 3;
529 } if p.zeta_d > 0.0 {
531 n += 5;
532 } n
534 }
535 }
536}
537
538#[cfg(test)]
539mod tests {
540 use super::*;
541
542 #[test]
543 fn test_xtb_params_exist() {
544 assert!(get_xtb_params(1).is_some());
545 assert!(get_xtb_params(6).is_some());
546 assert!(get_xtb_params(26).is_some());
547 assert!(get_xtb_params(78).is_some());
548 assert!(get_xtb_params(92).is_none()); }
550
551 #[test]
552 fn test_xtb_electron_count() {
553 assert_eq!(count_xtb_electrons(&[8, 1, 1]), 8); assert_eq!(count_xtb_electrons(&[6, 1, 1, 1, 1]), 8); }
556
557 #[test]
558 fn test_xtb_basis_count() {
559 assert_eq!(num_xtb_basis_functions(1), 1); assert_eq!(num_xtb_basis_functions(6), 4); assert_eq!(num_xtb_basis_functions(26), 9); }
563}