|
1 | 1 | # ********************************************************************************* |
2 | | -# * Copyright (C) 2025 Alexey V. Akimov |
| 2 | +# * Copyright (C) 2025 Daeho Han and Alexey V. Akimov |
3 | 3 | # * |
4 | 4 | # * This file is distributed under the terms of the GNU General Public License |
5 | 5 | # * as published by the Free Software Foundation, either version 3 of |
|
18 | 18 | List of classes: |
19 | 19 | * ldr_solver |
20 | 20 |
|
21 | | -.. moduleauthor:: Alexey V. Akimov, Daeho Han |
| 21 | +.. moduleauthor:: Daeho Han and Alexey V. Akimov |
22 | 22 |
|
23 | 23 | """ |
24 | 24 |
|
25 | | -__author__ = "Alexey V. Akimov" |
| 25 | +__author__ = "Daeho Han, Alexey V. Akimov" |
26 | 26 | __copyright__ = "Copyright 2025 Alexey V. Akimov" |
27 | | -__credits__ = ["Alexey V. Akimov"] |
| 27 | +__credits__ = ["Daeho Han", "Alexey V. Akimov"] |
28 | 28 | __license__ = "GNU-3" |
29 | 29 | __version__ = "1.0" |
30 | 30 | __maintainer__ = "Alexey V. Akimov" |
@@ -184,23 +184,38 @@ def initialize_C(self): |
184 | 184 | Initialize coefficient vector self.C0 at t=0, assuming: |
185 | 185 | - electronic state self.istate |
186 | 186 | - nuclear wavefunction is a Gaussian centered at self.q0 and self.p0, i.e. |
187 | | - chi0 = exp( alpha0 * (qgrid point - self.q0)**2 + i * self.p0 * (qgrid point - self.q0) ) |
| 187 | + chi0(q;q0,p0) = exp( - alpha0 * (q - self.q0)**2 + i * self.p0 * (q - self.q0) ) |
188 | 188 | alpha0 = 0.5/s_q **2; s_q = (1/(self.k * self.mass)) **0.25 |
| 189 | + |
| 190 | + For the Gaussian overlap calculation, consult with the formula in Begušić, T.; Vaníček, J. J. Chem. Phys. 2020, 153 (18), 184110. |
| 191 | +
|
189 | 192 | Sets: |
190 | 193 | self.C0 : complex-valued coefficient vector of shape (ndim) |
191 | 194 | """ |
192 | 195 | N, ist = self.ngrids, self.istate |
193 | 196 |
|
194 | | - s_q = (1.0/(self.k*self.mass)) ** 0.25 |
195 | | - alpha0 = 1/(2*s_q**2) |
| 197 | + q0 = self.q0.to(torch.cdouble) |
| 198 | + p0 = self.p0.to(torch.cdouble) |
| 199 | + qgrid = self.qgrid.to(torch.cdouble) |
| 200 | + alpha = self.alpha.to(torch.cdouble) |
| 201 | + |
| 202 | + s_q = (1.0 / (self.k*self.mass) ) ** 0.25 |
| 203 | + alpha0 = 1 / ( 2 * s_q **2 ) |
| 204 | + alpha0 = alpha0.to(torch.cdouble) |
| 205 | + |
| 206 | + # Width matrix |
| 207 | + Ag, A = torch.diag(2.j * self.alpha), torch.diag(2.j * alpha0) |
| 208 | + delta_A = A - Ag.conj() |
| 209 | + delta_A_inv = torch.torch.linalg.inv(delta_A) |
196 | 210 |
|
197 | 211 | # Compute Gaussian nuclear wavefunction at each grid point |
198 | 212 | for n in range(N): |
199 | 213 | index = ist * N + n |
200 | 214 |
|
201 | | - qn = self.qgrid[n] # (D,) |
202 | | - delta = qn - self.q0 # (D,) |
203 | | - exponent = -torch.dot(alpha0, delta**2) + .1j * torch.dot(self.p0, delta) |
| 215 | + xi0, xig = p0 - torch.matmul(A, q0), -torch.matmul(Ag, qgrid[n]) |
| 216 | + delta_xi = xi0 - xig.conj() |
| 217 | + delta_eta = -0.5 * torch.dot(xi0 + p0, q0) + 0.5 * torch.dot(xig, qgrid[n]).conj() |
| 218 | + exponent = -1.j * 0.5 * torch.dot(delta_xi, torch.matmul(delta_A_inv, delta_xi)) + 1.j * delta_eta |
204 | 219 |
|
205 | 220 | self.C0[index] = torch.exp(exponent) |
206 | 221 |
|
|
0 commit comments