|
27 | 27 | from pyscf.pbc import tools |
28 | 28 | from gpu4pyscf.lib import logger, utils |
29 | 29 | from gpu4pyscf.lib.cupy_helper import ( |
30 | | - return_cupy_array, contract, tag_array, sandwich_dot) |
| 30 | + return_cupy_array, contract, tag_array, sandwich_dot, eigh) |
31 | 31 | from gpu4pyscf.scf import hf as mol_hf |
32 | 32 | from gpu4pyscf.pbc.scf import hf as pbchf |
33 | 33 | from gpu4pyscf.pbc import df |
@@ -168,6 +168,9 @@ def energy_elec(mf, dm_kpts=None, h1e_kpts=None, vhf_kpts=None): |
168 | 168 | return (e1+e_coul).real, e_coul.real |
169 | 169 |
|
170 | 170 | def canonicalize(mf, mo_coeff_kpts, mo_occ_kpts, fock=None): |
| 171 | + if hasattr(mf, 'overlap_canonical_decomposed_x') and mf.overlap_canonical_decomposed_x is not None: |
| 172 | + raise NotImplementedError("Overlap matrix canonical decomposition (removing linear dependency for diffused orbitals) " |
| 173 | + "not supported for canonicalize() function with k-point sampling") |
171 | 174 | if fock is None: |
172 | 175 | dm = mf.make_rdm1(mo_coeff_kpts, mo_occ_kpts) |
173 | 176 | fock = mf.get_fock(dm=dm) |
@@ -389,10 +392,26 @@ def eig(self, h_kpts, s_kpts): |
389 | 392 | nkpts, nao = h_kpts.shape[:2] |
390 | 393 | eig_kpts = cp.empty((nkpts, nao)) |
391 | 394 | mo_coeff_kpts = cp.empty((nkpts, nao, nao), dtype=h_kpts.dtype) |
392 | | - for k in range(nkpts): |
393 | | - e, c = self._eigh(h_kpts[k], s_kpts[k]) |
394 | | - eig_kpts[k] = e |
395 | | - mo_coeff_kpts[k] = c |
| 395 | + |
| 396 | + x_kpts = None |
| 397 | + if hasattr(self, 'overlap_canonical_decomposed_x') and self.overlap_canonical_decomposed_x is not None: |
| 398 | + x_kpts = [cp.asarray(x) for x in self.overlap_canonical_decomposed_x] |
| 399 | + |
| 400 | + if x_kpts is None: |
| 401 | + for k in range(nkpts): |
| 402 | + e, c = eigh(h_kpts[k], s_kpts[k]) |
| 403 | + eig_kpts[k] = e |
| 404 | + mo_coeff_kpts[k] = c |
| 405 | + else: |
| 406 | + for k in range(nkpts): |
| 407 | + xk = x_kpts[k] |
| 408 | + ek, ck = cp.linalg.eigh(xk.T.conj() @ h_kpts[k] @ xk) |
| 409 | + ck = xk @ ck |
| 410 | + _, nmo_k = xk.shape |
| 411 | + eig_kpts[k, :nmo_k] = ek |
| 412 | + eig_kpts[k, nmo_k:] = float(cp.max(cp.abs(ek))) * 2 + 1e5 |
| 413 | + mo_coeff_kpts[k, :, :nmo_k] = ck |
| 414 | + mo_coeff_kpts[k, :, nmo_k:] = 0 |
396 | 415 | return eig_kpts, mo_coeff_kpts |
397 | 416 |
|
398 | 417 | def make_rdm1(self, mo_coeff_kpts=None, mo_occ_kpts=None, **kwargs): |
|
0 commit comments