Skip to main content

energy_r2scan_d3zero/
energy_r2scan_d3zero.rs

1#![cfg(feature = "api-v0_4")]
2
3use dftd3::prelude::*;
4
5fn main_test() {
6    // atom indices
7    let numbers = vec![6, 6, 6, 6, 6, 6, 53, 1, 1, 1, 1, 1, 16, 1, 6, 1, 1, 1];
8    // geometry in angstrom
9    #[rustfmt::skip]
10    let positions = vec![
11        -0.755422531,  -0.796459123,  -1.023590391,
12         0.634274834,  -0.880017014,  -1.075233285,
13         1.406955202,   0.199695367,  -0.653144334,
14         0.798863737,   1.361204515,  -0.180597909,
15        -0.593166787,   1.434312023,  -0.133597923,
16        -1.376239198,   0.359205222,  -0.553258516,
17        -1.514344238,   3.173268101,   0.573601106,
18         1.110906949,  -1.778801728,  -1.440619836,
19         1.399172302,   2.197767355,   0.147412751,
20         2.486417780,   0.142466525,  -0.689380574,
21        -2.454252250,   0.422581120,  -0.512807958,
22        -1.362353593,  -1.630564523,  -1.348743149,
23        -3.112683203,   6.289227834,   1.226984439,
24        -4.328789697,   5.797771251,   0.973373089,
25        -2.689135032,   6.703163830,  -0.489062886,
26        -1.684433029,   7.115457372,  -0.460265708,
27        -2.683867206,   5.816530502,  -1.115183775,
28        -3.365330613,   7.451201412,  -0.890098894,
29    ];
30    // convert angstrom to bohr
31    let positions = positions.iter().map(|&x| x / 0.52917721067).collect::<Vec<f64>>();
32    // generate DFTD3 model
33    let model = DFTD3Model::new(&numbers, &positions, None, None);
34    // explicitly set DFTD3 parameters
35    for atm in [true, false] {
36        let energy_ref = if atm { -0.01410721853585842 } else { -0.014100267345314462 };
37
38        let param = DFTD3ZeroDampingParamBuilder::default()
39            .s8(1.683)
40            .rs6(1.139)
41            .s9(if atm { 1.0 } else { 0.0 })
42            .init();
43        // obtain the dispersion energy without gradient and sigma
44        let (energy, _, _) = model.get_dispersion(&param, false).into();
45
46        println!("Dispersion energy: {}", energy);
47        assert!((energy - energy_ref).abs() < 1e-9);
48
49        // this way to provide custom damping parameter is also valid
50        let param = DFTD3ZeroDampingParam {
51            s6: 1.0,
52            s8: 1.683,
53            rs6: 1.139,
54            rs8: 1.0,
55            alp: 14.0,
56            s9: if atm { 1.0 } else { 0.0 },
57        };
58        let param = param.new_param();
59        // obtain the dispersion energy without gradient and sigma
60        let (energy, _, _) = model.get_dispersion(&param, false).into();
61
62        println!("Dispersion energy: {}", energy);
63        assert!((energy - energy_ref).abs() < 1e-9);
64
65        // this way to provide custom damping parameter is also valid
66        let param = DFTD3Param::new_zero_damping(
67            1.0,                         // s6
68            1.683,                       // s8
69            if atm { 1.0 } else { 0.0 }, // s9
70            1.139,                       // rs6
71            1.0,                         // rs8
72            14.0,                        // alp
73        );
74        // obtain the dispersion energy without gradient and sigma
75        let (energy, _, _) = model.get_dispersion(&param, false).into();
76
77        println!("Dispersion energy: {}", energy);
78        assert!((energy - energy_ref).abs() < 1e-9);
79    }
80}
81
82#[test]
83fn test() {
84    main_test();
85}
86
87fn main() {
88    main_test();
89}
90
91/* equivalent PySCF with dftd3
92
93// https://github.com/dftd3/simple-dftd3/blob/v1.2.1/python/dftd3/test_pyscf.py#L59-L102
94
95```python
96import pyscf
97from pyscf import gto
98import dftd3.pyscf as disp
99
100
101mol = gto.M(atom="""
102    C   -0.755422531  -0.796459123  -1.023590391
103    C    0.634274834  -0.880017014  -1.075233285
104    C    1.406955202   0.199695367  -0.653144334
105    C    0.798863737   1.361204515  -0.180597909
106    C   -0.593166787   1.434312023  -0.133597923
107    C   -1.376239198   0.359205222  -0.553258516
108    I   -1.514344238   3.173268101   0.573601106
109    H    1.110906949  -1.778801728  -1.440619836
110    H    1.399172302   2.197767355   0.147412751
111    H    2.486417780   0.142466525  -0.689380574
112    H   -2.454252250   0.422581120  -0.512807958
113    H   -1.362353593  -1.630564523  -1.348743149
114    S   -3.112683203   6.289227834   1.226984439
115    H   -4.328789697   5.797771251   0.973373089
116    C   -2.689135032   6.703163830  -0.489062886
117    H   -1.684433029   7.115457372  -0.460265708
118    H   -2.683867206   5.816530502  -1.115183775
119    H   -3.365330613   7.451201412  -0.890098894
120""")
121
122for atm in (True, False):
123    d3 = disp.DFTD3Dispersion(
124        mol,
125        param={
126            "s6": 1.0,
127            "s8": 1.683,
128            "rs6": 1.139,
129            "rs8": 1.0,
130            "alp": 14.0,
131            "s9": 1.0 if atm else 0.0,
132        },
133        version="d3zero",
134    )
135    print(d3.kernel()[0])
136```
137
138*/