pyscf 2.6.2__py3-none-macosx_11_0_arm64.whl → 2.8.0__py3-none-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (360) hide show
  1. pyscf/__init__.py +2 -2
  2. pyscf/adc/__init__.py +3 -8
  3. pyscf/adc/dfadc.py +22 -6
  4. pyscf/adc/radc.py +106 -15
  5. pyscf/adc/radc_amplitudes.py +7 -1
  6. pyscf/adc/radc_ao2mo.py +4 -2
  7. pyscf/adc/radc_ea.py +524 -8
  8. pyscf/adc/radc_ip.py +492 -60
  9. pyscf/adc/radc_ip_cvs.py +4 -2
  10. pyscf/adc/uadc.py +116 -27
  11. pyscf/adc/uadc_amplitudes.py +215 -20
  12. pyscf/adc/uadc_ao2mo.py +30 -9
  13. pyscf/adc/uadc_ea.py +34 -44
  14. pyscf/adc/uadc_ip.py +9 -4
  15. pyscf/adc/uadc_ip_cvs.py +4 -1
  16. pyscf/agf2/__init__.py +2 -2
  17. pyscf/agf2/aux_space.py +1 -1
  18. pyscf/agf2/chkfile.py +1 -1
  19. pyscf/ao2mo/__init__.py +13 -2
  20. pyscf/ao2mo/_ao2mo.py +10 -1
  21. pyscf/ao2mo/incore.py +3 -0
  22. pyscf/ao2mo/nrr_outcore.py +2 -2
  23. pyscf/ao2mo/outcore.py +9 -7
  24. pyscf/ao2mo/r_outcore.py +2 -2
  25. pyscf/cc/__init__.py +21 -3
  26. pyscf/cc/bccd.py +0 -46
  27. pyscf/cc/ccsd.py +29 -13
  28. pyscf/cc/ccsd_rdm.py +6 -1
  29. pyscf/cc/gccsd.py +2 -2
  30. pyscf/cc/uccsd.py +7 -7
  31. pyscf/cc/uccsd_rdm.py +2 -2
  32. pyscf/data/elements.py +1 -1
  33. pyscf/df/__init__.py +2 -1
  34. pyscf/df/addons.py +79 -51
  35. pyscf/df/autoaux.py +195 -0
  36. pyscf/df/df.py +5 -1
  37. pyscf/df/df_jk.py +27 -25
  38. pyscf/df/grad/casscf.py +0 -41
  39. pyscf/df/grad/rhf.py +31 -1
  40. pyscf/df/hessian/rhf.py +2 -10
  41. pyscf/df/hessian/rks.py +1 -7
  42. pyscf/df/hessian/uhf.py +3 -13
  43. pyscf/df/hessian/uks.py +1 -8
  44. pyscf/df/incore.py +18 -6
  45. pyscf/df/outcore.py +6 -6
  46. pyscf/dft/dks.py +1 -1
  47. pyscf/dft/gks.py +25 -21
  48. pyscf/dft/libxc.py +91 -645
  49. pyscf/dft/numint.py +40 -19
  50. pyscf/dft/radi.py +48 -7
  51. pyscf/dft/rks.py +29 -25
  52. pyscf/dft/roks.py +7 -1
  53. pyscf/dft/uks.py +34 -25
  54. pyscf/dft/xc_deriv.py +1 -1
  55. pyscf/dft/xcfun.py +53 -2
  56. pyscf/eph/eph_fd.py +1 -1
  57. pyscf/eph/rhf.py +6 -36
  58. pyscf/eph/rks.py +0 -4
  59. pyscf/eph/uhf.py +1 -7
  60. pyscf/eph/uks.py +1 -7
  61. pyscf/fci/addons.py +117 -2
  62. pyscf/fci/cistring.py +1 -1
  63. pyscf/fci/direct_nosym.py +3 -3
  64. pyscf/fci/direct_spin0_symm.py +22 -43
  65. pyscf/fci/direct_spin1.py +65 -10
  66. pyscf/fci/direct_spin1_symm.py +49 -14
  67. pyscf/fci/direct_uhf.py +4 -4
  68. pyscf/fci/selected_ci_symm.py +1 -1
  69. pyscf/grad/ccsd.py +3 -7
  70. pyscf/grad/ccsd_slow.py +2 -3
  71. pyscf/grad/lagrange.py +11 -3
  72. pyscf/grad/mp2.py +13 -4
  73. pyscf/grad/sacasscf.py +1 -1
  74. pyscf/grad/tdrks.py +1 -1
  75. pyscf/grad/uccsd.py +3 -7
  76. pyscf/grad/ump2.py +2 -4
  77. pyscf/gto/basis/__init__.py +17 -4
  78. pyscf/gto/basis/bse.py +68 -15
  79. pyscf/gto/basis/def2-mtzvp.dat +4719 -0
  80. pyscf/gto/basis/def2-mtzvpp.dat +4739 -0
  81. pyscf/gto/basis/dyall-basis/__init__.py +0 -0
  82. pyscf/gto/basis/dyall-basis/dyall_2zp.py +6492 -0
  83. pyscf/gto/basis/dyall-basis/dyall_3zp.py +8343 -0
  84. pyscf/gto/basis/dyall-basis/dyall_4zp.py +10055 -0
  85. pyscf/gto/basis/dyall-basis/dyall_aae2z.py +1818 -0
  86. pyscf/gto/basis/dyall-basis/dyall_aae3z.py +2521 -0
  87. pyscf/gto/basis/dyall-basis/dyall_aae4z.py +3351 -0
  88. pyscf/gto/basis/dyall-basis/dyall_acv2z.py +1790 -0
  89. pyscf/gto/basis/dyall-basis/dyall_acv3z.py +2417 -0
  90. pyscf/gto/basis/dyall-basis/dyall_acv4z.py +3085 -0
  91. pyscf/gto/basis/dyall-basis/dyall_ae2z.py +6619 -0
  92. pyscf/gto/basis/dyall-basis/dyall_ae3z.py +9027 -0
  93. pyscf/gto/basis/dyall-basis/dyall_ae4z.py +11839 -0
  94. pyscf/gto/basis/dyall-basis/dyall_av2z.py +1742 -0
  95. pyscf/gto/basis/dyall-basis/dyall_av3z.py +2318 -0
  96. pyscf/gto/basis/dyall-basis/dyall_av4z.py +2905 -0
  97. pyscf/gto/basis/dyall-basis/dyall_cv2z.py +6558 -0
  98. pyscf/gto/basis/dyall-basis/dyall_cv3z.py +8767 -0
  99. pyscf/gto/basis/dyall-basis/dyall_cv4z.py +11098 -0
  100. pyscf/gto/basis/dyall-basis/dyall_v2z.py +6472 -0
  101. pyscf/gto/basis/dyall-basis/dyall_v3z.py +8539 -0
  102. pyscf/gto/basis/dyall-basis/dyall_v4z.py +10658 -0
  103. pyscf/gto/basis/ma-def2-qzvp.dat +5959 -0
  104. pyscf/gto/basis/ma-def2-qzvpp.dat +6195 -0
  105. pyscf/gto/basis/ma-def2-svp.dat +3504 -0
  106. pyscf/gto/basis/ma-def2-svpp.dat +3504 -0
  107. pyscf/gto/basis/ma-def2-tzvp.dat +4347 -0
  108. pyscf/gto/basis/ma-def2-tzvpp.dat +4549 -0
  109. pyscf/gto/basis/parse_cp2k.py +8 -7
  110. pyscf/gto/basis/parse_cp2k_pp.py +1 -1
  111. pyscf/gto/basis/parse_nwchem.py +26 -11
  112. pyscf/gto/basis/parse_nwchem_ecp.py +2 -1
  113. pyscf/gto/basis/sap_grasp_large.dat +2438 -0
  114. pyscf/gto/basis/sap_grasp_small.dat +1434 -0
  115. pyscf/gto/eval_gto.py +1 -1
  116. pyscf/gto/ft_ao.py +6 -6
  117. pyscf/gto/mole.py +123 -71
  118. pyscf/gto/moleintor.py +1 -1
  119. pyscf/gw/gw_ac.py +2 -2
  120. pyscf/gw/gw_cd.py +2 -2
  121. pyscf/gw/rpa.py +135 -246
  122. pyscf/gw/ugw_ac.py +2 -2
  123. pyscf/gw/urpa.py +80 -131
  124. pyscf/hessian/rhf.py +30 -128
  125. pyscf/hessian/rks.py +1 -6
  126. pyscf/hessian/uhf.py +28 -138
  127. pyscf/hessian/uks.py +1 -8
  128. pyscf/lib/CMakeLists.txt +6 -2
  129. pyscf/lib/ao2mo/nr_ao2mo.c +1 -1
  130. pyscf/lib/ao2mo/nrr_ao2mo.c +1 -1
  131. pyscf/lib/ao2mo/r_ao2mo.c +1 -1
  132. pyscf/lib/cc/ccsd_pack.c +1 -1
  133. pyscf/lib/cc/ccsd_t.c +6 -6
  134. pyscf/lib/cc/uccsd_t.c +4 -4
  135. pyscf/lib/config.h +0 -1
  136. pyscf/lib/config.h.in +0 -1
  137. pyscf/lib/deps/include/XCFun/XCFunExport.h +1 -0
  138. pyscf/lib/deps/include/xc.h +28 -18
  139. pyscf/lib/deps/include/xc_funcs.h +50 -2
  140. pyscf/lib/deps/include/xc_version.h +3 -3
  141. pyscf/lib/deps/lib/libcint.6.dylib +0 -0
  142. pyscf/lib/deps/lib/{libxc.12.dylib → libxc.15.dylib} +0 -0
  143. pyscf/lib/deps/lib/libxcfun.2.dylib +0 -0
  144. pyscf/lib/dft/grid_common.c +1 -1
  145. pyscf/lib/dft/libxc_itrf.c +10 -7
  146. pyscf/lib/dft/nr_numint_sparse.c +3 -3
  147. pyscf/lib/dft/xcfun_itrf.c +1 -1
  148. pyscf/lib/diis.py +2 -2
  149. pyscf/lib/exceptions.py +6 -0
  150. pyscf/lib/gto/fill_grids_int2c.c +11 -9
  151. pyscf/lib/gto/fill_int2e.c +7 -5
  152. pyscf/lib/gto/fill_r_4c.c +1 -1
  153. pyscf/lib/gto/ft_ao.c +1 -1
  154. pyscf/lib/gto/ft_ao.h +1 -1
  155. pyscf/lib/gto/gto.h +2 -2
  156. pyscf/lib/gto/nr_ecp.c +3 -2
  157. pyscf/lib/libagf2.dylib +0 -0
  158. pyscf/lib/libao2mo.dylib +0 -0
  159. pyscf/lib/libcc.dylib +0 -0
  160. pyscf/lib/libcgto.dylib +0 -0
  161. pyscf/lib/libcvhf.dylib +0 -0
  162. pyscf/lib/libdft.dylib +0 -0
  163. pyscf/lib/libfci.dylib +0 -0
  164. pyscf/lib/libmcscf.dylib +0 -0
  165. pyscf/lib/libmp.dylib +0 -0
  166. pyscf/lib/libnp_helper.dylib +0 -0
  167. pyscf/lib/libpbc.dylib +0 -0
  168. pyscf/lib/libri.dylib +0 -0
  169. pyscf/lib/libxc_itrf.dylib +0 -0
  170. pyscf/lib/libxcfun_itrf.dylib +0 -0
  171. pyscf/lib/linalg_helper.py +117 -198
  172. pyscf/lib/logger.py +2 -1
  173. pyscf/lib/mcscf/fci_contract.c +10 -3
  174. pyscf/lib/misc.py +63 -22
  175. pyscf/lib/mp/CMakeLists.txt +22 -0
  176. pyscf/lib/mp/mp2.c +518 -0
  177. pyscf/lib/mp/mp2.h +44 -0
  178. pyscf/lib/np_helper/CMakeLists.txt +1 -1
  179. pyscf/lib/np_helper/imatcopy.c +360 -0
  180. pyscf/lib/np_helper/np_helper.c +94 -0
  181. pyscf/lib/np_helper/np_helper.h +26 -0
  182. pyscf/lib/numpy_helper.py +195 -11
  183. pyscf/lib/pbc/nr_direct.c +2 -7
  184. pyscf/lib/pbc/nr_ecp.c +10 -3
  185. pyscf/lib/pbc/pbc.h +1 -1
  186. pyscf/lib/vhf/fblas.h +3 -0
  187. pyscf/lib/vhf/nr_sgx_direct.c +8 -6
  188. pyscf/lib/vhf/nr_sr_vhf.c +8 -12
  189. pyscf/lib/vhf/optimizer.c +2 -2
  190. pyscf/lib/vhf/rkb_screen.c +139 -0
  191. pyscf/lo/iao.py +1 -1
  192. pyscf/lo/ibo.py +3 -3
  193. pyscf/lo/pipek_jacobi.py +1 -1
  194. pyscf/mcscf/__init__.py +2 -2
  195. pyscf/mcscf/addons.py +3 -3
  196. pyscf/mcscf/apc.py +2 -2
  197. pyscf/mcscf/casci.py +13 -7
  198. pyscf/mcscf/chkfile.py +69 -41
  199. pyscf/mcscf/dmet_cas.py +2 -2
  200. pyscf/mcscf/mc1step.py +72 -44
  201. pyscf/mcscf/newton_casscf.py +5 -5
  202. pyscf/mcscf/ucasci.py +1 -1
  203. pyscf/mcscf/umc1step.py +49 -28
  204. pyscf/md/integrators.py +3 -3
  205. pyscf/mp/__init__.py +1 -0
  206. pyscf/mp/dfmp2.py +498 -59
  207. pyscf/mp/dfmp2_native.py +11 -1
  208. pyscf/mp/dfmp2_slow.py +133 -0
  209. pyscf/mp/dfump2.py +672 -0
  210. pyscf/mp/dfump2_native.py +9 -0
  211. pyscf/mp/dfump2_slow.py +161 -0
  212. pyscf/mp/gmp2.py +6 -47
  213. pyscf/mp/mp2.py +25 -10
  214. pyscf/mp/ump2.py +30 -24
  215. pyscf/pbc/adc/kadc_rhf.py +1 -1
  216. pyscf/pbc/adc/kadc_rhf_amplitudes.py +2 -2
  217. pyscf/pbc/ao2mo/eris.py +1 -1
  218. pyscf/pbc/cc/kccsd_rhf.py +3 -3
  219. pyscf/pbc/cc/kccsd_t_rhf.py +2 -2
  220. pyscf/pbc/ci/kcis_rhf.py +2 -2
  221. pyscf/pbc/df/aft.py +8 -9
  222. pyscf/pbc/df/aft_ao2mo.py +1 -1
  223. pyscf/pbc/df/df.py +85 -12
  224. pyscf/pbc/df/df_jk.py +6 -2
  225. pyscf/pbc/df/fft.py +9 -5
  226. pyscf/pbc/df/fft_ao2mo.py +4 -0
  227. pyscf/pbc/df/fft_jk.py +18 -10
  228. pyscf/pbc/df/ft_ao.py +4 -3
  229. pyscf/pbc/df/gdf_builder.py +5 -4
  230. pyscf/pbc/df/incore.py +2 -2
  231. pyscf/pbc/df/mdf.py +6 -3
  232. pyscf/pbc/df/mdf_jk.py +2 -1
  233. pyscf/pbc/df/outcore.py +10 -10
  234. pyscf/pbc/df/rsdf.py +2 -2
  235. pyscf/pbc/df/rsdf_builder.py +13 -8
  236. pyscf/pbc/df/rsdf_helper.py +6 -6
  237. pyscf/pbc/df/rsdf_jk.py +2 -1
  238. pyscf/pbc/dft/cdft.py +5 -5
  239. pyscf/pbc/dft/gen_grid.py +3 -2
  240. pyscf/pbc/dft/gks.py +14 -3
  241. pyscf/pbc/dft/kgks.py +15 -4
  242. pyscf/pbc/dft/krks.py +28 -10
  243. pyscf/pbc/dft/krks_ksymm.py +21 -9
  244. pyscf/pbc/dft/krkspu.py +1 -30
  245. pyscf/pbc/dft/krkspu_ksymm.py +0 -30
  246. pyscf/pbc/dft/kuks.py +30 -13
  247. pyscf/pbc/dft/kuks_ksymm.py +22 -10
  248. pyscf/pbc/dft/kukspu.py +0 -27
  249. pyscf/pbc/dft/kukspu_ksymm.py +0 -30
  250. pyscf/pbc/dft/multigrid/multigrid.py +36 -33
  251. pyscf/pbc/dft/multigrid/multigrid_pair.py +7 -2
  252. pyscf/pbc/dft/multigrid/pp.py +1 -1
  253. pyscf/pbc/dft/numint.py +56 -31
  254. pyscf/pbc/dft/rks.py +16 -24
  255. pyscf/pbc/dft/uks.py +21 -4
  256. pyscf/pbc/eph/eph_fd.py +1 -1
  257. pyscf/pbc/geomopt/geometric_solver.py +1 -1
  258. pyscf/pbc/gto/_pbcintor.py +1 -0
  259. pyscf/pbc/gto/cell.py +194 -23
  260. pyscf/pbc/gto/ecp.py +12 -12
  261. pyscf/pbc/gto/eval_gto.py +3 -3
  262. pyscf/pbc/gto/neighborlist.py +4 -1
  263. pyscf/pbc/gto/pseudo/pp.py +1 -1
  264. pyscf/pbc/gw/krgw_ac.py +4 -4
  265. pyscf/pbc/gw/krgw_cd.py +4 -4
  266. pyscf/pbc/gw/kugw_ac.py +3 -3
  267. pyscf/pbc/lib/kpts_helper.py +4 -3
  268. pyscf/pbc/lib/linalg_helper.py +1 -1
  269. pyscf/pbc/mp/kmp2.py +1 -1
  270. pyscf/pbc/mpitools/mpi.py +1 -1
  271. pyscf/pbc/scf/_response_functions.py +141 -34
  272. pyscf/pbc/scf/addons.py +15 -11
  273. pyscf/pbc/scf/cphf.py +1 -1
  274. pyscf/pbc/scf/ghf.py +1 -1
  275. pyscf/pbc/scf/hf.py +21 -32
  276. pyscf/pbc/scf/kghf.py +33 -29
  277. pyscf/pbc/scf/khf.py +103 -29
  278. pyscf/pbc/scf/khf_ksymm.py +15 -1
  279. pyscf/pbc/scf/krohf.py +5 -7
  280. pyscf/pbc/scf/kuhf.py +54 -23
  281. pyscf/pbc/scf/kuhf_ksymm.py +1 -1
  282. pyscf/pbc/scf/rsjk.py +14 -10
  283. pyscf/pbc/scf/scfint.py +1 -1
  284. pyscf/pbc/scf/stability.py +27 -15
  285. pyscf/pbc/scf/uhf.py +3 -1
  286. pyscf/pbc/symm/symmetry.py +2 -2
  287. pyscf/pbc/tdscf/krhf.py +238 -154
  288. pyscf/pbc/tdscf/krks.py +1 -45
  289. pyscf/pbc/tdscf/kuhf.py +319 -171
  290. pyscf/pbc/tdscf/kuks.py +0 -56
  291. pyscf/pbc/tdscf/rhf.py +116 -3
  292. pyscf/pbc/tdscf/rks.py +2 -1
  293. pyscf/pbc/tdscf/uhf.py +214 -1
  294. pyscf/pbc/tdscf/uks.py +2 -1
  295. pyscf/pbc/tools/k2gamma.py +20 -6
  296. pyscf/pbc/tools/lattice.py +3 -3
  297. pyscf/pbc/tools/pbc.py +111 -91
  298. pyscf/pbc/tools/pyscf_ase.py +0 -1
  299. pyscf/pbc/tools/pywannier90.py +1 -1
  300. pyscf/qmmm/mm_mole.py +1 -1
  301. pyscf/scf/_response_functions.py +87 -46
  302. pyscf/scf/_vhf.py +15 -10
  303. pyscf/scf/addons.py +29 -15
  304. pyscf/scf/cphf.py +14 -52
  305. pyscf/scf/dhf.py +121 -38
  306. pyscf/scf/dispersion.py +10 -9
  307. pyscf/scf/ghf.py +25 -13
  308. pyscf/scf/ghf_symm.py +2 -2
  309. pyscf/scf/hf.py +262 -30
  310. pyscf/scf/rohf.py +37 -5
  311. pyscf/scf/stability.py +142 -112
  312. pyscf/scf/ucphf.py +21 -16
  313. pyscf/scf/uhf.py +104 -61
  314. pyscf/sgx/sgx.py +1 -1
  315. pyscf/sgx/sgx_jk.py +4 -4
  316. pyscf/solvent/__init__.py +2 -2
  317. pyscf/solvent/_attach_solvent.py +2 -0
  318. pyscf/solvent/_ddcosmo_tdscf_grad.py +1 -1
  319. pyscf/solvent/cosmors.py +366 -0
  320. pyscf/solvent/ddcosmo.py +1 -1
  321. pyscf/solvent/pcm.py +4 -4
  322. pyscf/solvent/pol_embed.py +1 -1
  323. pyscf/solvent/smd.py +5 -3
  324. pyscf/soscf/ciah.py +3 -11
  325. pyscf/soscf/newton_ah.py +5 -2
  326. pyscf/symm/__init__.py +1 -1
  327. pyscf/symm/addons.py +5 -5
  328. pyscf/symm/geom.py +1 -5
  329. pyscf/tdscf/_lr_eig.py +1002 -0
  330. pyscf/tdscf/dhf.py +84 -87
  331. pyscf/tdscf/dks.py +0 -4
  332. pyscf/tdscf/ghf.py +139 -127
  333. pyscf/tdscf/gks.py +27 -25
  334. pyscf/tdscf/rhf.py +194 -147
  335. pyscf/tdscf/rks.py +26 -22
  336. pyscf/tdscf/uhf.py +166 -118
  337. pyscf/tdscf/uks.py +32 -31
  338. pyscf/tools/fcidump.py +3 -0
  339. pyscf/tools/qcschema.py +265 -0
  340. pyscf/x2c/sfx2c1e.py +1 -1
  341. pyscf/x2c/tdscf.py +41 -41
  342. pyscf/x2c/x2c.py +15 -11
  343. {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/METADATA +39 -36
  344. {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/NOTICE +14 -1
  345. {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/RECORD +348 -316
  346. {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/WHEEL +1 -1
  347. pyscf/dft/gen_libxc_param.py +0 -35
  348. pyscf/dft/gen_xcfun_param.py +0 -209
  349. pyscf/pbc/tdscf/kproxy.py +0 -189
  350. pyscf/pbc/tdscf/kproxy_supercell.py +0 -664
  351. pyscf/pbc/tdscf/krhf_slow.py +0 -300
  352. pyscf/pbc/tdscf/krhf_slow_gamma.py +0 -175
  353. pyscf/pbc/tdscf/krhf_slow_supercell.py +0 -250
  354. pyscf/pbc/tdscf/proxy.py +0 -39
  355. pyscf/pbc/tdscf/rhf_slow.py +0 -35
  356. pyscf/tdscf/common_slow.py +0 -799
  357. pyscf/tdscf/proxy.py +0 -258
  358. pyscf/tdscf/rhf_slow.py +0 -181
  359. {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/LICENSE +0 -0
  360. {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/top_level.txt +0 -0
pyscf/tdscf/ghf.py CHANGED
@@ -25,14 +25,13 @@
25
25
  from functools import reduce
26
26
  import numpy
27
27
  from pyscf import lib
28
- from pyscf import dft
29
- from pyscf.dft import numint
28
+ from pyscf import scf
30
29
  from pyscf import ao2mo
31
30
  from pyscf import symm
32
31
  from pyscf.lib import logger
33
32
  from pyscf.tdscf import rhf
33
+ from pyscf.tdscf._lr_eig import eigh as lr_eigh, eig as lr_eig
34
34
  from pyscf.scf import ghf_symm
35
- from pyscf.data import nist
36
35
  from pyscf import __config__
37
36
 
38
37
  OUTPUT_THRESHOLD = getattr(__config__, 'tdscf_rhf_get_nto_threshold', 0.3)
@@ -46,6 +45,7 @@ def gen_tda_operation(mf, fock_ao=None, wfnsym=None):
46
45
  wfnsym : int or str
47
46
  Point group symmetry irrep symbol or ID for excited CIS wavefunction.
48
47
  '''
48
+ assert fock_ao is None
49
49
  mol = mf.mol
50
50
  mo_coeff = mf.mo_coeff
51
51
  mo_energy = mf.mo_energy
@@ -62,21 +62,9 @@ def gen_tda_operation(mf, fock_ao=None, wfnsym=None):
62
62
  if isinstance(wfnsym, str):
63
63
  wfnsym = symm.irrep_name2id(mol.groupname, wfnsym)
64
64
  wfnsym = wfnsym % 10 # convert to D2h subgroup
65
- orbsym = ghf_symm.get_orbsym(mol, mo_coeff)
66
- orbsym_in_d2h = numpy.asarray(orbsym) % 10 # convert to D2h irreps
67
- sym_forbid = (orbsym_in_d2h[occidx,None] ^ orbsym_in_d2h[viridx]) != wfnsym
68
-
69
- if fock_ao is None:
70
- #dm0 = mf.make_rdm1(mo_coeff, mo_occ)
71
- #fock_ao = mf.get_hcore() + mf.get_veff(mol, dm0)
72
- foo = numpy.diag(mo_energy[occidx])
73
- fvv = numpy.diag(mo_energy[viridx])
74
- else:
75
- fock = reduce(numpy.dot, (mo_coeff.conj().T, fock_ao, mo_coeff))
76
- foo = fock[occidx[:,None],occidx]
77
- fvv = fock[viridx[:,None],viridx]
65
+ sym_forbid = _get_x_sym_table(mf) != wfnsym
78
66
 
79
- hdiag = fvv.diagonal() - foo.diagonal()[:,None]
67
+ e_ia = hdiag = mo_energy[viridx] - mo_energy[occidx,None]
80
68
  if wfnsym is not None and mol.symmetry:
81
69
  hdiag[sym_forbid] = 0
82
70
  hdiag = hdiag.ravel().real
@@ -90,23 +78,30 @@ def gen_tda_operation(mf, fock_ao=None, wfnsym=None):
90
78
  zs = numpy.copy(zs)
91
79
  zs[:,sym_forbid] = 0
92
80
 
93
- dmov = lib.einsum('xov,qv,po->xpq', zs, orbv.conj(), orbo)
94
- v1ao = vresp(dmov)
95
- v1ov = lib.einsum('xpq,po,qv->xov', v1ao, orbo.conj(), orbv)
96
- v1ov += lib.einsum('xqs,sp->xqp', zs, fvv)
97
- v1ov -= lib.einsum('xpr,sp->xsr', zs, foo)
81
+ dms = lib.einsum('xov,pv,qo->xpq', zs, orbv, orbo.conj())
82
+ v1ao = vresp(dms)
83
+ v1mo = lib.einsum('xpq,qo,pv->xov', v1ao, orbo, orbv.conj())
84
+ v1mo += numpy.einsum('xia,ia->xia', zs, e_ia)
98
85
  if wfnsym is not None and mol.symmetry:
99
- v1ov[:,sym_forbid] = 0
100
- return v1ov.reshape(v1ov.shape[0],-1)
86
+ v1mo[:,sym_forbid] = 0
87
+ return v1mo.reshape(v1mo.shape[0],-1)
101
88
 
102
89
  return vind, hdiag
103
90
  gen_tda_hop = gen_tda_operation
104
91
 
92
+ def _get_x_sym_table(mf):
93
+ '''Irrep (up to D2h symmetry) of each coefficient in X[nocc,nvir]'''
94
+ mol = mf.mol
95
+ mo_occ = mf.mo_occ
96
+ orbsym = ghf_symm.get_orbsym(mol, mf.mo_coeff)
97
+ orbsym = numpy.asarray(orbsym) % 10 # convert to D2h irreps
98
+ return orbsym[mo_occ==1,None] ^ orbsym[mo_occ==0]
99
+
105
100
  def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
106
101
  r'''A and B matrices for TDDFT response function.
107
102
 
108
- A[i,a,j,b] = \delta_{ab}\delta_{ij}(E_a - E_i) + (ia||bj)
109
- B[i,a,j,b] = (ia||jb)
103
+ A[i,a,j,b] = \delta_{ab}\delta_{ij}(E_a - E_i) + (ai||jb)
104
+ B[i,a,j,b] = (ai||bj)
110
105
  '''
111
106
  if mo_energy is None: mo_energy = mf.mo_energy
112
107
  if mo_coeff is None: mo_coeff = mf.mo_coeff
@@ -128,7 +123,7 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
128
123
  orbob = orbo[nao:]
129
124
  nmo = nocc + nvir
130
125
 
131
- e_ia = lib.direct_sum('a-i->ia', mo_energy[viridx], mo_energy[occidx])
126
+ e_ia = mo_energy[viridx] - mo_energy[occidx,None]
132
127
  a = numpy.diag(e_ia.ravel()).reshape(nocc,nvir,nocc,nvir).astype(mo_coeff.dtype)
133
128
  b = numpy.zeros_like(a)
134
129
 
@@ -145,13 +140,13 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
145
140
  eri_mo_a+= lib.einsum('pqrs,pi,qj->ijrs', eri_ao, orbob.conj(), mob)
146
141
  eri_mo = lib.einsum('ijrs,rk,sl->ijkl', eri_mo_a, moa.conj(), moa)
147
142
  eri_mo+= lib.einsum('ijrs,rk,sl->ijkl', eri_mo_a, mob.conj(), mob)
148
- a += numpy.einsum('iabj->iajb', eri_mo[:nocc,nocc:,nocc:,:nocc])
149
- a -= numpy.einsum('ijba->iajb', eri_mo[:nocc,:nocc,nocc:,nocc:]) * hyb
150
- b += numpy.einsum('iajb->iajb', eri_mo[:nocc,nocc:,:nocc,nocc:])
151
- b -= numpy.einsum('jaib->iajb', eri_mo[:nocc,nocc:,:nocc,nocc:]) * hyb
143
+ a += numpy.einsum('iabj->iajb', eri_mo[:nocc,nocc:,nocc:,:nocc].conj())
144
+ a -= numpy.einsum('ijba->iajb', eri_mo[:nocc,:nocc,nocc:,nocc:].conj()) * hyb
145
+ b += numpy.einsum('iajb->iajb', eri_mo[:nocc,nocc:,:nocc,nocc:].conj())
146
+ b -= numpy.einsum('jaib->iajb', eri_mo[:nocc,nocc:,:nocc,nocc:].conj()) * hyb
152
147
  return a, b
153
148
 
154
- if isinstance(mf, dft.KohnShamDFT):
149
+ if isinstance(mf, scf.hf.KohnShamDFT):
155
150
  from pyscf.dft import xc_deriv
156
151
  ni = mf._numint
157
152
  ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True)
@@ -162,6 +157,7 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
162
157
  raise NotImplementedError
163
158
 
164
159
  omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, mol.spin)
160
+ assert omega == 0.
165
161
 
166
162
  a, b = add_hf_(a, b, hyb)
167
163
 
@@ -207,9 +203,9 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
207
203
  rho_ov_bb = numpy.einsum('ri,ra->ria', mo_ob.conj(), mo_vb)
208
204
  rho_ov = ud2tm(rho_ov_aa, rho_ov_ab, rho_ov_ba, rho_ov_bb)
209
205
  rho_vo = rho_ov.conj()
210
- w_ov = numpy.einsum('tsr,tria->sria', wfxc, rho_ov)
211
- a += lib.einsum('sria,srjb->iajb', w_ov, rho_vo)
212
- b += lib.einsum('sria,srjb->iajb', w_ov, rho_ov)
206
+ w_vo = numpy.einsum('tsr,tria->sria', wfxc, rho_vo)
207
+ a += lib.einsum('sria,srjb->iajb', w_vo, rho_ov)
208
+ b += lib.einsum('sria,srjb->iajb', w_vo, rho_vo)
213
209
  elif ni.collinear[0] == 'c':
214
210
  rho = ni.eval_rho(mol, ao, dm0, mask, xctype, hermi=1, with_lapl=False)
215
211
  fxc = ni.eval_xc_eff(mf.xc, rho, deriv=2)[2]
@@ -219,13 +215,13 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
219
215
  rho_ov_b = numpy.einsum('ri,ra->ria', mo_ob.conj(), mo_vb)
220
216
  rho_vo_a = rho_ov_a.conj()
221
217
  rho_vo_b = rho_ov_b.conj()
222
- w_ov = wv_a[:,:,None,None] * rho_ov_a
223
- w_ov += wv_b[:,:,None,None] * rho_ov_b
224
- wa_ov, wb_ov = w_ov
225
- a += lib.einsum('ria,rjb->iajb', wa_ov, rho_vo_a)
226
- a += lib.einsum('ria,rjb->iajb', wb_ov, rho_vo_b)
227
- b += lib.einsum('ria,rjb->iajb', wa_ov, rho_ov_a)
228
- b += lib.einsum('ria,rjb->iajb', wb_ov, rho_ov_b)
218
+ w_vo = wv_a[:,:,None,None] * rho_vo_a
219
+ w_vo += wv_b[:,:,None,None] * rho_vo_b
220
+ wa_vo, wb_vo = w_vo
221
+ a += lib.einsum('ria,rjb->iajb', wa_vo, rho_ov_a)
222
+ a += lib.einsum('ria,rjb->iajb', wb_vo, rho_ov_b)
223
+ b += lib.einsum('ria,rjb->iajb', wa_vo, rho_vo_a)
224
+ b += lib.einsum('ria,rjb->iajb', wb_vo, rho_vo_b)
229
225
  else:
230
226
  raise NotImplementedError(ni.collinear)
231
227
 
@@ -250,9 +246,9 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
250
246
  rho_ov_bb[1:4] += numpy.einsum('xri,ra->xria', mo_ob[1:4].conj(), mo_vb[0])
251
247
  rho_ov = ud2tm(rho_ov_aa, rho_ov_ab, rho_ov_ba, rho_ov_bb)
252
248
  rho_vo = rho_ov.conj()
253
- w_ov = numpy.einsum('txsyr,txria->syria', wfxc, rho_ov)
254
- a += lib.einsum('syria,syrjb->iajb', w_ov, rho_vo)
255
- b += lib.einsum('syria,syrjb->iajb', w_ov, rho_ov)
249
+ w_vo = numpy.einsum('txsyr,txria->syria', wfxc, rho_vo)
250
+ a += lib.einsum('syria,syrjb->iajb', w_vo, rho_ov)
251
+ b += lib.einsum('syria,syrjb->iajb', w_vo, rho_vo)
256
252
  elif ni.collinear[0] == 'c':
257
253
  rho = ni.eval_rho(mol, ao, dm0, mask, xctype, hermi=1, with_lapl=False)
258
254
  fxc = ni.eval_xc_eff(mf.xc, rho, deriv=2)[2]
@@ -264,13 +260,13 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
264
260
  rho_ov_b[1:4] += numpy.einsum('ri,xra->xria', mo_ob[0].conj(), mo_vb[1:4])
265
261
  rho_vo_a = rho_ov_a.conj()
266
262
  rho_vo_b = rho_ov_b.conj()
267
- w_ov = numpy.einsum('xsyr,xria->syria', wv_a, rho_ov_a)
268
- w_ov += numpy.einsum('xsyr,xria->syria', wv_b, rho_ov_b)
269
- wa_ov, wb_ov = w_ov
270
- a += lib.einsum('xria,xrjb->iajb', wa_ov, rho_vo_a)
271
- a += lib.einsum('xria,xrjb->iajb', wb_ov, rho_vo_b)
272
- b += lib.einsum('xria,xrjb->iajb', wa_ov, rho_ov_a)
273
- b += lib.einsum('xria,xrjb->iajb', wb_ov, rho_ov_b)
263
+ w_vo = numpy.einsum('xsyr,xria->syria', wv_a, rho_vo_a)
264
+ w_vo += numpy.einsum('xsyr,xria->syria', wv_b, rho_vo_b)
265
+ wa_vo, wb_vo = w_vo
266
+ a += lib.einsum('xria,xrjb->iajb', wa_vo, rho_ov_a)
267
+ a += lib.einsum('xria,xrjb->iajb', wb_vo, rho_ov_b)
268
+ b += lib.einsum('xria,xrjb->iajb', wa_vo, rho_vo_a)
269
+ b += lib.einsum('xria,xrjb->iajb', wb_vo, rho_vo_b)
274
270
  else:
275
271
  raise NotImplementedError(ni.collinear)
276
272
 
@@ -309,9 +305,9 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
309
305
  rho_ov_bb = numpy.vstack([rho_ov_bb, tau_ov_bb[numpy.newaxis]])
310
306
  rho_ov = ud2tm(rho_ov_aa, rho_ov_ab, rho_ov_ba, rho_ov_bb)
311
307
  rho_vo = rho_ov.conj()
312
- w_ov = numpy.einsum('txsyr,txria->syria', wfxc, rho_ov)
313
- a += lib.einsum('syria,syrjb->iajb', w_ov, rho_vo)
314
- b += lib.einsum('syria,syrjb->iajb', w_ov, rho_ov)
308
+ w_vo = numpy.einsum('txsyr,txria->syria', wfxc, rho_vo)
309
+ a += lib.einsum('syria,syrjb->iajb', w_vo, rho_ov)
310
+ b += lib.einsum('syria,syrjb->iajb', w_vo, rho_vo)
315
311
  elif ni.collinear[0] == 'c':
316
312
  rho = ni.eval_rho(mol, ao, dm0, mask, xctype, hermi=1, with_lapl=False)
317
313
  fxc = ni.eval_xc_eff(mf.xc, rho, deriv=2)[2]
@@ -327,13 +323,13 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
327
323
  rho_ov_b = numpy.vstack([rho_ov_b, tau_ov_b[numpy.newaxis]])
328
324
  rho_vo_a = rho_ov_a.conj()
329
325
  rho_vo_b = rho_ov_b.conj()
330
- w_ov = numpy.einsum('xsyr,xria->syria', wv_a, rho_ov_a)
331
- w_ov += numpy.einsum('xsyr,xria->syria', wv_b, rho_ov_b)
332
- wa_ov, wb_ov = w_ov
333
- a += lib.einsum('xria,xrjb->iajb', wa_ov, rho_vo_a)
334
- a += lib.einsum('xria,xrjb->iajb', wb_ov, rho_vo_b)
335
- b += lib.einsum('xria,xrjb->iajb', wa_ov, rho_ov_a)
336
- b += lib.einsum('xria,xrjb->iajb', wb_ov, rho_ov_b)
326
+ w_vo = numpy.einsum('xsyr,xria->syria', wv_a, rho_vo_a)
327
+ w_vo += numpy.einsum('xsyr,xria->syria', wv_b, rho_vo_b)
328
+ wa_vo, wb_vo = w_vo
329
+ a += lib.einsum('xria,xrjb->iajb', wa_vo, rho_ov_a)
330
+ a += lib.einsum('xria,xrjb->iajb', wb_vo, rho_ov_b)
331
+ b += lib.einsum('xria,xrjb->iajb', wa_vo, rho_vo_a)
332
+ b += lib.einsum('xria,xrjb->iajb', wb_vo, rho_vo_b)
337
333
  else:
338
334
  raise NotImplementedError(ni.collinear)
339
335
 
@@ -378,7 +374,7 @@ class TDA(TDBase):
378
374
  mf = self._scf
379
375
  return gen_tda_hop(mf, wfnsym=self.wfnsym)
380
376
 
381
- def init_guess(self, mf, nstates=None, wfnsym=None):
377
+ def init_guess(self, mf, nstates=None, wfnsym=None, return_symmetry=False):
382
378
  if nstates is None: nstates = self.nstates
383
379
  if wfnsym is None: wfnsym = self.wfnsym
384
380
 
@@ -386,27 +382,36 @@ class TDA(TDBase):
386
382
  mo_occ = mf.mo_occ
387
383
  occidx = numpy.where(mo_occ==1)[0]
388
384
  viridx = numpy.where(mo_occ==0)[0]
389
- e_ia = mo_energy[viridx] - mo_energy[occidx,None]
390
-
391
- if wfnsym is not None and mf.mol.symmetry:
392
- if isinstance(wfnsym, str):
393
- wfnsym = symm.irrep_name2id(mf.mol.groupname, wfnsym)
394
- wfnsym = wfnsym % 10 # convert to D2h subgroup
395
- orbsym = ghf_symm.get_orbsym(mf.mol, mf.mo_coeff)
396
- orbsym_in_d2h = numpy.asarray(orbsym) % 10 # convert to D2h irreps
397
- e_ia[(orbsym_in_d2h[occidx,None] ^ orbsym_in_d2h[viridx]) != wfnsym] = 1e99
398
-
385
+ e_ia = (mo_energy[viridx] - mo_energy[occidx,None]).ravel()
399
386
  nov = e_ia.size
400
387
  nstates = min(nstates, nov)
401
- e_ia = e_ia.ravel()
402
- e_threshold = numpy.sort(e_ia)[nstates-1]
388
+
389
+ if (wfnsym is not None or return_symmetry) and mf.mol.symmetry:
390
+ x_sym = _get_x_sym_table(mf).ravel()
391
+ if wfnsym is not None:
392
+ if isinstance(wfnsym, str):
393
+ wfnsym = symm.irrep_name2id(mf.mol.groupname, wfnsym)
394
+ wfnsym = wfnsym % 10 # convert to D2h subgroup
395
+ e_ia[x_sym != wfnsym] = 1e99
396
+ nov_allowed = numpy.count_nonzero(x_sym == wfnsym)
397
+ nstates = min(nstates, nov_allowed)
398
+
399
+ e_threshold = numpy.partition(e_ia, nstates-1)[nstates-1]
403
400
  e_threshold += self.deg_eia_thresh
404
401
 
405
402
  idx = numpy.where(e_ia <= e_threshold)[0]
406
403
  x0 = numpy.zeros((idx.size, nov))
407
404
  for i, j in enumerate(idx):
408
405
  x0[i, j] = 1 # Koopmans' excitations
409
- return x0
406
+
407
+ if return_symmetry:
408
+ if mf.mol.symmetry:
409
+ x0sym = x_sym[idx]
410
+ else:
411
+ x0sym = None
412
+ return x0, x0sym
413
+ else:
414
+ return x0
410
415
 
411
416
  def kernel(self, x0=None, nstates=None):
412
417
  '''TDA diagonalization solver
@@ -418,6 +423,7 @@ class TDA(TDBase):
418
423
  nstates = self.nstates
419
424
  else:
420
425
  self.nstates = nstates
426
+ mol = self.mol
421
427
 
422
428
  log = logger.Logger(self.stdout, self.verbose)
423
429
 
@@ -428,17 +434,18 @@ class TDA(TDBase):
428
434
  idx = numpy.where(w > self.positive_eig_threshold)[0]
429
435
  return w[idx], v[:,idx], idx
430
436
 
437
+ x0sym = None
431
438
  if x0 is None:
432
- x0 = self.init_guess(self._scf, self.nstates)
439
+ x0, x0sym = self.init_guess(
440
+ self._scf, self.nstates, return_symmetry=True)
441
+ elif mol.symmetry:
442
+ x_sym = _get_x_sym_table(self._scf).ravel()
443
+ x0sym = [rhf._guess_wfnsym_id(self, x_sym, x) for x in x0]
433
444
 
434
- # FIXME: Is it correct to call davidson1 for complex integrals
435
- self.converged, self.e, x1 = \
436
- lib.davidson1(vind, x0, precond,
437
- tol=self.conv_tol,
438
- nroots=nstates, lindep=self.lindep,
439
- max_cycle=self.max_cycle,
440
- max_space=self.max_space, pick=pickeig,
441
- verbose=log)
445
+ self.converged, self.e, x1 = lr_eigh(
446
+ vind, x0, precond, tol_residual=self.conv_tol, lindep=self.lindep,
447
+ nroots=nstates, x0sym=x0sym, pick=pickeig, max_cycle=self.max_cycle,
448
+ max_memory=self.max_memory, verbose=log)
442
449
 
443
450
  nocc = (self._scf.mo_occ>0).sum()
444
451
  nmo = self._scf.mo_occ.size
@@ -478,19 +485,11 @@ def gen_tdhf_operation(mf, fock_ao=None, wfnsym=None):
478
485
  if isinstance(wfnsym, str):
479
486
  wfnsym = symm.irrep_name2id(mol.groupname, wfnsym)
480
487
  wfnsym = wfnsym % 10 # convert to D2h subgroup
481
- orbsym = ghf_symm.get_orbsym(mol, mo_coeff)
482
- orbsym_in_d2h = numpy.asarray(orbsym) % 10 # convert to D2h irreps
483
- sym_forbid = (orbsym_in_d2h[occidx,None] ^ orbsym_in_d2h[viridx]) != wfnsym
484
-
485
- #dm0 = mf.make_rdm1(mo_coeff, mo_occ)
486
- #fock_ao = mf.get_hcore() + mf.get_veff(mol, dm0)
487
- #fock = reduce(numpy.dot, (mo_coeff.T, fock_ao, mo_coeff))
488
- #foo = fock[occidx[:,None],occidx]
489
- #fvv = fock[viridx[:,None],viridx]
490
- foo = numpy.diag(mo_energy[occidx])
491
- fvv = numpy.diag(mo_energy[viridx])
492
-
493
- hdiag = fvv.diagonal() - foo.diagonal()[:,None]
488
+ sym_forbid = _get_x_sym_table(mf) != wfnsym
489
+
490
+ assert fock_ao is None
491
+
492
+ e_ia = hdiag = mo_energy[viridx] - mo_energy[occidx,None]
494
493
  if wfnsym is not None and mol.symmetry:
495
494
  hdiag[sym_forbid] = 0
496
495
  hdiag = numpy.hstack((hdiag.ravel(), -hdiag.ravel())).real
@@ -506,25 +505,28 @@ def gen_tdhf_operation(mf, fock_ao=None, wfnsym=None):
506
505
  xys[:,:,sym_forbid] = 0
507
506
 
508
507
  xs, ys = xys.transpose(1,0,2,3)
509
- # dms = AX + BY
510
- dms = lib.einsum('xov,qv,po->xpq', xs, orbv.conj(), orbo)
511
- dms += lib.einsum('xov,pv,qo->xpq', ys, orbv, orbo.conj())
512
-
513
- v1ao = vresp(dms)
514
- v1ov = lib.einsum('xpq,po,qv->xov', v1ao, orbo.conj(), orbv)
515
- v1vo = lib.einsum('xpq,qo,pv->xov', v1ao, orbo, orbv.conj())
516
- v1ov += lib.einsum('xqs,sp->xqp', xs, fvv) # AX
517
- v1ov -= lib.einsum('xpr,sp->xsr', xs, foo) # AX
518
- v1vo += lib.einsum('xqs,sp->xqp', ys, fvv.conj()) # (A*)Y
519
- v1vo -= lib.einsum('xpr,sp->xsr', ys, foo.conj()) # (A*)Y
508
+ dms = lib.einsum('xov,pv,qo->xpq', xs, orbv, orbo.conj())
509
+ dms += lib.einsum('xov,qv,po->xpq', ys, orbv.conj(), orbo)
510
+ v1ao = vresp(dms) # = <mj||nb> Xjb + <mb||nj> Yjb
511
+ # A ~= <aj||ib>, B = <ab||ij>
512
+ # AX + BY
513
+ # = <aj||ib> Xjb + <ab||ij> Yjb
514
+ # = (<mj||nb> Xjb + <mb||nj> Yjb) Cma* Cni
515
+ v1_top = lib.einsum('xpq,qo,pv->xov', v1ao, orbo, orbv.conj())
516
+ # (B*)X + (A*)Y
517
+ # = <ij||ab> Xjb + <ib||aj> Yjb
518
+ # = (<mj||nb> Xjb + <mb||nj> Yjb) Cmi* Cna
519
+ v1_bot = lib.einsum('xpq,po,qv->xov', v1ao, orbo.conj(), orbv)
520
+ v1_top += numpy.einsum('xia,ia->xia', xs, e_ia) # AX
521
+ v1_bot += numpy.einsum('xia,ia->xia', ys, e_ia) # (A*)Y
520
522
 
521
523
  if wfnsym is not None and mol.symmetry:
522
- v1ov[:,sym_forbid] = 0
523
- v1vo[:,sym_forbid] = 0
524
+ v1_top[:,sym_forbid] = 0
525
+ v1_bot[:,sym_forbid] = 0
524
526
 
525
527
  # (AX, (-A*)Y)
526
528
  nz = xys.shape[0]
527
- hx = numpy.hstack((v1ov.reshape(nz,-1), -v1vo.reshape(nz,-1)))
529
+ hx = numpy.hstack((v1_top.reshape(nz,-1), -v1_bot.reshape(nz,-1)))
528
530
  return hx
529
531
 
530
532
  return vind, hdiag
@@ -540,10 +542,15 @@ class TDHF(TDBase):
540
542
  mf = self._scf
541
543
  return gen_tdhf_operation(mf, wfnsym=self.wfnsym)
542
544
 
543
- def init_guess(self, mf, nstates=None, wfnsym=None):
544
- x0 = TDA.init_guess(self, mf, nstates, wfnsym)
545
- y0 = numpy.zeros_like(x0)
546
- return numpy.asarray(numpy.block([[x0, y0], [y0, x0.conj()]]))
545
+ def init_guess(self, mf, nstates=None, wfnsym=None, return_symmetry=False):
546
+ if return_symmetry:
547
+ x0, x0sym = TDA.init_guess(self, mf, nstates, wfnsym, return_symmetry)
548
+ y0 = numpy.zeros_like(x0)
549
+ return numpy.hstack([x0, y0]), x0sym
550
+ else:
551
+ x0 = TDA.init_guess(self, mf, nstates, wfnsym, return_symmetry)
552
+ y0 = numpy.zeros_like(x0)
553
+ return numpy.hstack([x0, y0])
547
554
 
548
555
  def kernel(self, x0=None, nstates=None):
549
556
  '''TDHF diagonalization with non-Hermitian eigenvalue solver
@@ -555,6 +562,7 @@ class TDHF(TDBase):
555
562
  nstates = self.nstates
556
563
  else:
557
564
  self.nstates = nstates
565
+ mol = self.mol
558
566
 
559
567
  log = logger.Logger(self.stdout, self.verbose)
560
568
 
@@ -568,16 +576,19 @@ class TDHF(TDBase):
568
576
  # FIXME: Should the amplitudes be real? It also affects x2c-tdscf
569
577
  return lib.linalg_helper._eigs_cmplx2real(w, v, realidx, ensure_real)
570
578
 
579
+ x0sym = None
571
580
  if x0 is None:
572
- x0 = self.init_guess(self._scf, self.nstates)
573
-
574
- self.converged, w, x1 = \
575
- lib.davidson_nosym1(vind, x0, precond,
576
- tol=self.conv_tol,
577
- nroots=nstates, lindep=self.lindep,
578
- max_cycle=self.max_cycle,
579
- max_space=self.max_space, pick=pickeig,
580
- verbose=log)
581
+ x0, x0sym = self.init_guess(
582
+ self._scf, self.nstates, return_symmetry=True)
583
+ elif mol.symmetry:
584
+ x_sym = y_sym = _get_x_sym_table(self._scf).ravel()
585
+ x_sym = numpy.append(x_sym, y_sym)
586
+ x0sym = [rhf._guess_wfnsym_id(self, x_sym, x) for x in x0]
587
+
588
+ self.converged, w, x1 = lr_eig(
589
+ vind, x0, precond, tol_residual=self.conv_tol, lindep=self.lindep,
590
+ nroots=nstates, x0sym=x0sym, pick=pickeig, max_cycle=self.max_cycle,
591
+ max_memory=self.max_memory, verbose=log)
581
592
 
582
593
  nocc = (self._scf.mo_occ>0).sum()
583
594
  nmo = self._scf.mo_occ.size
@@ -586,7 +597,9 @@ class TDHF(TDBase):
586
597
  def norm_xy(z):
587
598
  x, y = z.reshape(2,nocc,nvir)
588
599
  norm = lib.norm(x)**2 - lib.norm(y)**2
589
- norm = numpy.sqrt(1./norm)
600
+ if norm < 0:
601
+ log.warn('TDDFT amplitudes |X| smaller than |Y|')
602
+ norm = abs(norm)**-.5
590
603
  return x*norm, y*norm
591
604
  self.xy = [norm_xy(z) for z in x1]
592
605
 
@@ -600,6 +613,5 @@ class TDHF(TDBase):
600
613
 
601
614
  RPA = TDGHF = TDHF
602
615
 
603
- from pyscf import scf
604
616
  scf.ghf.GHF.TDA = lib.class_as_method(TDA)
605
617
  scf.ghf.GHF.TDHF = lib.class_as_method(TDHF)
pyscf/tdscf/gks.py CHANGED
@@ -20,10 +20,8 @@
20
20
  import numpy
21
21
  from pyscf import lib
22
22
  from pyscf import symm
23
- from pyscf.tdscf import ghf
24
- from pyscf.scf import ghf_symm
25
- from pyscf.scf import _response_functions # noqa
26
- from pyscf.data import nist
23
+ from pyscf.tdscf import ghf, rhf
24
+ from pyscf.tdscf._lr_eig import eigh as lr_eigh
27
25
  from pyscf.dft.rks import KohnShamDFT
28
26
  from pyscf import __config__
29
27
 
@@ -39,6 +37,7 @@ RPA = TDGKS = TDDFT
39
37
  class CasidaTDDFT(TDDFT, TDA):
40
38
  '''Solve the Casida TDDFT formula (A-B)(A+B)(X+Y) = (X+Y)w^2
41
39
  '''
40
+
42
41
  init_guess = TDA.init_guess
43
42
 
44
43
  def gen_vind(self, mf=None):
@@ -62,9 +61,7 @@ class CasidaTDDFT(TDDFT, TDA):
62
61
  if isinstance(wfnsym, str):
63
62
  wfnsym = symm.irrep_name2id(mol.groupname, wfnsym)
64
63
  wfnsym = wfnsym % 10 # convert to D2h subgroup
65
- orbsym = ghf_symm.get_orbsym(mol, mo_coeff)
66
- orbsym_in_d2h = numpy.asarray(orbsym) % 10 # convert to D2h irreps
67
- sym_forbid = (orbsym_in_d2h[occidx,None] ^ orbsym_in_d2h[viridx]) != wfnsym
64
+ sym_forbid = ghf._get_x_sym_table(mf) != wfnsym
68
65
 
69
66
  e_ia = (mo_energy[viridx].reshape(-1,1) - mo_energy[occidx]).T
70
67
  if wfnsym is not None and mol.symmetry:
@@ -81,19 +78,19 @@ class CasidaTDDFT(TDDFT, TDA):
81
78
  zs = numpy.copy(zs)
82
79
  zs[:,sym_forbid] = 0
83
80
 
84
- dmov = lib.einsum('xov,qv,po->xpq', zs*d_ia, orbv, orbo)
81
+ dms = lib.einsum('xov,pv,qo->xpq', zs*d_ia, orbv, orbo)
85
82
  # +cc for A+B because K_{ai,jb} in A == K_{ai,bj} in B
86
- dmov = dmov + dmov.transpose(0,2,1)
83
+ dms = dms + dms.transpose(0,2,1)
87
84
 
88
- v1ao = vresp(dmov)
89
- v1ov = lib.einsum('xpq,po,qv->xov', v1ao, orbo, orbv)
85
+ v1ao = vresp(dms)
86
+ v1mo = lib.einsum('xpq,qo,pv->xov', v1ao, orbo, orbv)
90
87
 
91
- # numpy.sqrt(e_ia) * (e_ia*d_ia*z + v1ov)
92
- v1ov += numpy.einsum('xov,ov->xov', zs, ed_ia)
93
- v1ov *= d_ia
88
+ # numpy.sqrt(e_ia) * (e_ia*d_ia*z + v1mo)
89
+ v1mo += numpy.einsum('xov,ov->xov', zs, ed_ia)
90
+ v1mo *= d_ia
94
91
  if wfnsym is not None and mol.symmetry:
95
- v1ov[:,sym_forbid] = 0
96
- return v1ov.reshape(v1ov.shape[0],-1)
92
+ v1mo[:,sym_forbid] = 0
93
+ return v1mo.reshape(v1mo.shape[0],-1)
97
94
 
98
95
  return vind, hdiag
99
96
 
@@ -101,6 +98,7 @@ class CasidaTDDFT(TDDFT, TDA):
101
98
  '''TDDFT diagonalization solver
102
99
  '''
103
100
  cpu0 = (lib.logger.process_clock(), lib.logger.perf_counter())
101
+ mol = self.mol
104
102
  mf = self._scf
105
103
  if mf._numint.libxc.is_hybrid_xc(mf.xc):
106
104
  raise RuntimeError('%s cannot be used with hybrid functional'
@@ -121,16 +119,18 @@ class CasidaTDDFT(TDDFT, TDA):
121
119
  idx = numpy.where(w > self.positive_eig_threshold)[0]
122
120
  return w[idx], v[:,idx], idx
123
121
 
122
+ x0sym = None
124
123
  if x0 is None:
125
- x0 = self.init_guess(self._scf, self.nstates)
124
+ x0, x0sym = self.init_guess(
125
+ self._scf, self.nstates, return_symmetry=True)
126
+ elif mol.symmetry:
127
+ x_sym = ghf._get_x_sym_table(self._scf).ravel()
128
+ x0sym = [rhf._guess_wfnsym_id(self, x_sym, x) for x in x0]
126
129
 
127
- self.converged, w2, x1 = \
128
- lib.davidson1(vind, x0, precond,
129
- tol=self.conv_tol,
130
- nroots=nstates, lindep=self.lindep,
131
- max_cycle=self.max_cycle,
132
- max_space=self.max_space, pick=pickeig,
133
- verbose=log)
130
+ self.converged, w2, x1 = lr_eigh(
131
+ vind, x0, precond, tol_residual=self.conv_tol, lindep=self.lindep,
132
+ nroots=nstates, x0sym=x0sym, pick=pickeig, max_cycle=self.max_cycle,
133
+ max_memory=self.max_memory, verbose=log)
134
134
 
135
135
  mo_energy = self._scf.mo_energy
136
136
  mo_occ = self._scf.mo_occ
@@ -144,7 +144,9 @@ class CasidaTDDFT(TDDFT, TDA):
144
144
  x = (zp + zm) * .5
145
145
  y = (zp - zm) * .5
146
146
  norm = lib.norm(x)**2 - lib.norm(y)**2
147
- norm = numpy.sqrt(1./norm)
147
+ if norm < 0:
148
+ log.warn('TDDFT amplitudes |X| smaller than |Y|')
149
+ norm = abs(norm)**-.5
148
150
  return (x*norm, y*norm)
149
151
 
150
152
  idx = numpy.where(w2 > self.positive_eig_threshold)[0]