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/rks.py CHANGED
@@ -25,8 +25,7 @@ import numpy
25
25
  from pyscf import lib
26
26
  from pyscf import symm
27
27
  from pyscf.tdscf import rhf
28
- from pyscf.scf import hf_symm
29
- from pyscf.data import nist
28
+ from pyscf.tdscf._lr_eig import eigh as lr_eigh
30
29
  from pyscf.dft.rks import KohnShamDFT
31
30
  from pyscf import __config__
32
31
 
@@ -46,7 +45,9 @@ RPA = TDRKS = TDDFT
46
45
  class CasidaTDDFT(TDDFT, TDA):
47
46
  '''Solve the Casida TDDFT formula (A-B)(A+B)(X+Y) = (X+Y)w^2
48
47
  '''
48
+
49
49
  init_guess = TDA.init_guess
50
+ get_precond = TDA.get_precond
50
51
 
51
52
  def gen_vind(self, mf=None):
52
53
  if mf is None:
@@ -71,9 +72,7 @@ class CasidaTDDFT(TDDFT, TDA):
71
72
  if isinstance(wfnsym, str):
72
73
  wfnsym = symm.irrep_name2id(mol.groupname, wfnsym)
73
74
  wfnsym = wfnsym % 10 # convert to D2h subgroup
74
- orbsym = hf_symm.get_orbsym(mol, mo_coeff)
75
- orbsym_in_d2h = numpy.asarray(orbsym) % 10 # convert to D2h irreps
76
- sym_forbid = (orbsym_in_d2h[occidx,None] ^ orbsym_in_d2h[viridx]) != wfnsym
75
+ sym_forbid = rhf._get_x_sym_table(mf) != wfnsym
77
76
 
78
77
  e_ia = (mo_energy[viridx].reshape(-1,1) - mo_energy[occidx]).T
79
78
  if wfnsym is not None and mol.symmetry:
@@ -87,17 +86,17 @@ class CasidaTDDFT(TDDFT, TDA):
87
86
  def vind(zs):
88
87
  zs = numpy.asarray(zs).reshape(-1,nocc,nvir)
89
88
  # *2 for double occupancy
90
- dmov = lib.einsum('xov,ov,po,qv->xpq', zs, d_ia*2, orbo, orbv.conj())
89
+ dms = lib.einsum('xov,pv,qo->xpq', zs * (d_ia*2), orbv, orbo)
91
90
  # +cc for A+B and K_{ai,jb} in A == K_{ai,bj} in B
92
- dmov = dmov + dmov.conj().transpose(0,2,1)
91
+ dms = dms + dms.transpose(0,2,1)
93
92
 
94
- v1ao = vresp(dmov)
95
- v1ov = lib.einsum('xpq,po,qv->xov', v1ao, orbo.conj(), orbv)
93
+ v1ao = vresp(dms)
94
+ v1mo = lib.einsum('xpq,qo,pv->xov', v1ao, orbo, orbv)
96
95
 
97
- # numpy.sqrt(e_ia) * (e_ia*d_ia*z + v1ov)
98
- v1ov += numpy.einsum('xov,ov->xov', zs, ed_ia)
99
- v1ov *= d_ia
100
- return v1ov.reshape(v1ov.shape[0],-1)
96
+ # numpy.sqrt(e_ia) * (e_ia*d_ia*z + v1mo)
97
+ v1mo += numpy.einsum('xov,ov->xov', zs, ed_ia)
98
+ v1mo *= d_ia
99
+ return v1mo.reshape(v1mo.shape[0],-1)
101
100
 
102
101
  return vind, hdiag
103
102
 
@@ -105,6 +104,7 @@ class CasidaTDDFT(TDDFT, TDA):
105
104
  '''TDDFT diagonalization solver
106
105
  '''
107
106
  cpu0 = (lib.logger.process_clock(), lib.logger.perf_counter())
107
+ mol = self.mol
108
108
  mf = self._scf
109
109
  if mf._numint.libxc.is_hybrid_xc(mf.xc):
110
110
  raise RuntimeError('%s cannot be used with hybrid functional'
@@ -125,16 +125,18 @@ class CasidaTDDFT(TDDFT, TDA):
125
125
  idx = numpy.where(w > self.positive_eig_threshold)[0]
126
126
  return w[idx], v[:,idx], idx
127
127
 
128
+ x0sym = None
128
129
  if x0 is None:
129
- x0 = self.init_guess(self._scf, self.nstates)
130
+ x0, x0sym = self.init_guess(
131
+ self._scf, self.nstates, return_symmetry=True)
132
+ elif mol.symmetry:
133
+ x_sym = rhf._get_x_sym_table(mf).ravel()
134
+ x0sym = [rhf._guess_wfnsym_id(self, x_sym, x) for x in x0]
130
135
 
131
- self.converged, w2, x1 = \
132
- lib.davidson1(vind, x0, precond,
133
- tol=self.conv_tol,
134
- nroots=nstates, lindep=self.lindep,
135
- max_cycle=self.max_cycle,
136
- max_space=self.max_space, pick=pickeig,
137
- verbose=log)
136
+ self.converged, w2, x1 = lr_eigh(
137
+ vind, x0, precond, tol_residual=self.conv_tol, lindep=self.lindep,
138
+ nroots=nstates, x0sym=x0sym, pick=pickeig, max_cycle=self.max_cycle,
139
+ max_memory=self.max_memory, verbose=log)
138
140
 
139
141
  mo_energy = self._scf.mo_energy
140
142
  mo_occ = self._scf.mo_occ
@@ -148,7 +150,9 @@ class CasidaTDDFT(TDDFT, TDA):
148
150
  x = (zp + zm) * .5
149
151
  y = (zp - zm) * .5
150
152
  norm = lib.norm(x)**2 - lib.norm(y)**2
151
- norm = numpy.sqrt(.5/norm) # normalize to 0.5 for alpha spin
153
+ if norm < 0:
154
+ log.warn('TDDFT amplitudes |X| smaller than |Y|')
155
+ norm = abs(.5/norm)**.5 # normalize to 0.5 for alpha spin
152
156
  return (x*norm, y*norm)
153
157
 
154
158
  idx = numpy.where(w2 > self.positive_eig_threshold)[0]
pyscf/tdscf/uhf.py CHANGED
@@ -23,9 +23,9 @@ from pyscf import scf
23
23
  from pyscf import symm
24
24
  from pyscf import ao2mo
25
25
  from pyscf.lib import logger
26
- from pyscf.tdscf import rhf
27
26
  from pyscf.scf import uhf_symm
28
- from pyscf.scf import _response_functions
27
+ from pyscf.tdscf import rhf
28
+ from pyscf.tdscf._lr_eig import eigh as lr_eigh, eig as lr_eig, real_eig
29
29
  from pyscf.data import nist
30
30
  from pyscf import __config__
31
31
 
@@ -41,6 +41,7 @@ def gen_tda_operation(mf, fock_ao=None, wfnsym=None):
41
41
  wfnsym : int or str
42
42
  Point group symmetry irrep symbol or ID for excited CIS wavefunction.
43
43
  '''
44
+ assert fock_ao is None
44
45
  mol = mf.mol
45
46
  mo_coeff = mf.mo_coeff
46
47
  assert (mo_coeff[0].dtype == numpy.double)
@@ -63,13 +64,9 @@ def gen_tda_operation(mf, fock_ao=None, wfnsym=None):
63
64
  if wfnsym is not None and mol.symmetry:
64
65
  if isinstance(wfnsym, str):
65
66
  wfnsym = symm.irrep_name2id(mol.groupname, wfnsym)
66
- orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mo_coeff)
67
67
  wfnsym = wfnsym % 10 # convert to D2h subgroup
68
- orbsyma_in_d2h = numpy.asarray(orbsyma) % 10
69
- orbsymb_in_d2h = numpy.asarray(orbsymb) % 10
70
- sym_forbida = (orbsyma_in_d2h[occidxa,None] ^ orbsyma_in_d2h[viridxa]) != wfnsym
71
- sym_forbidb = (orbsymb_in_d2h[occidxb,None] ^ orbsymb_in_d2h[viridxb]) != wfnsym
72
- sym_forbid = numpy.hstack((sym_forbida.ravel(), sym_forbidb.ravel()))
68
+ x_sym_a, x_sym_b = _get_x_sym_table(mf)
69
+ sym_forbid = numpy.append(x_sym_a.ravel(), x_sym_b.ravel()) != wfnsym
73
70
 
74
71
  e_ia_a = mo_energy[0][viridxa] - mo_energy[0][occidxa,None]
75
72
  e_ia_b = mo_energy[1][viridxb] - mo_energy[1][occidxb,None]
@@ -83,24 +80,24 @@ def gen_tda_operation(mf, fock_ao=None, wfnsym=None):
83
80
  vresp = mf.gen_response(hermi=0, max_memory=max_memory)
84
81
 
85
82
  def vind(zs):
83
+ nz = len(zs)
86
84
  zs = numpy.asarray(zs)
87
85
  if wfnsym is not None and mol.symmetry:
88
86
  zs = numpy.copy(zs)
89
87
  zs[:,sym_forbid] = 0
90
88
 
91
- za = zs[:,:nocca*nvira].reshape(-1,nocca,nvira)
92
- zb = zs[:,nocca*nvira:].reshape(-1,noccb,nvirb)
93
- dmova = lib.einsum('xov,qv,po->xpq', za, orbva.conj(), orboa)
94
- dmovb = lib.einsum('xov,qv,po->xpq', zb, orbvb.conj(), orbob)
89
+ za = zs[:,:nocca*nvira].reshape(nz,nocca,nvira)
90
+ zb = zs[:,nocca*nvira:].reshape(nz,noccb,nvirb)
91
+ dmsa = lib.einsum('xov,pv,qo->xpq', za, orbva, orboa.conj())
92
+ dmsb = lib.einsum('xov,pv,qo->xpq', zb, orbvb, orbob.conj())
95
93
 
96
- v1ao = vresp(numpy.asarray((dmova,dmovb)))
94
+ v1ao = vresp(numpy.asarray((dmsa,dmsb)))
97
95
 
98
- v1a = lib.einsum('xpq,po,qv->xov', v1ao[0], orboa.conj(), orbva)
99
- v1b = lib.einsum('xpq,po,qv->xov', v1ao[1], orbob.conj(), orbvb)
96
+ v1a = lib.einsum('xpq,qo,pv->xov', v1ao[0], orboa, orbva.conj())
97
+ v1b = lib.einsum('xpq,qo,pv->xov', v1ao[1], orbob, orbvb.conj())
100
98
  v1a += numpy.einsum('xia,ia->xia', za, e_ia_a)
101
99
  v1b += numpy.einsum('xia,ia->xia', zb, e_ia_b)
102
100
 
103
- nz = zs.shape[0]
104
101
  hx = numpy.hstack((v1a.reshape(nz,-1), v1b.reshape(nz,-1)))
105
102
  if wfnsym is not None and mol.symmetry:
106
103
  hx[:,sym_forbid] = 0
@@ -109,11 +106,22 @@ def gen_tda_operation(mf, fock_ao=None, wfnsym=None):
109
106
  return vind, hdiag
110
107
  gen_tda_hop = gen_tda_operation
111
108
 
109
+ def _get_x_sym_table(mf):
110
+ '''Irrep (up to D2h symmetry) of each coefficient in X amplitude'''
111
+ mol = mf.mol
112
+ mo_occa, mo_occb = mf.mo_occ
113
+ orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mf.mo_coeff)
114
+ orbsyma = orbsyma % 10
115
+ orbsymb = orbsymb % 10
116
+ x_sym_a = orbsyma[mo_occa>0,None] ^ orbsyma[mo_occa==0]
117
+ x_sym_b = orbsymb[mo_occb>0,None] ^ orbsymb[mo_occb==0]
118
+ return x_sym_a, x_sym_b
119
+
112
120
  def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
113
121
  r'''A and B matrices for TDDFT response function.
114
122
 
115
- A[i,a,j,b] = \delta_{ab}\delta_{ij}(E_a - E_i) + (ia||bj)
116
- B[i,a,j,b] = (ia||jb)
123
+ A[i,a,j,b] = \delta_{ab}\delta_{ij}(E_a - E_i) + (ai||jb)
124
+ B[i,a,j,b] = (ai||bj)
117
125
 
118
126
  Spin symmetry is considered in the returned A, B lists. List A has three
119
127
  items: (A_aaaa, A_aabb, A_bbbb). A_bbaa = A_aabb.transpose(2,3,0,1).
@@ -124,6 +132,7 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
124
132
  if mo_coeff is None: mo_coeff = mf.mo_coeff
125
133
  if mo_occ is None: mo_occ = mf.mo_occ
126
134
 
135
+ assert mo_coeff[0].dtype == numpy.float64
127
136
  mol = mf.mol
128
137
  nao = mol.nao_nr()
129
138
  occidx_a = numpy.where(mo_occ[0]==1)[0]
@@ -183,11 +192,24 @@ def get_ab(mf, mo_energy=None, mo_coeff=None, mo_occ=None):
183
192
  ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True)
184
193
  if mf.do_nlc():
185
194
  logger.warn(mf, 'NLC functional found in DFT object. Its second '
186
- 'deriviative is not available. Its contribution is '
195
+ 'derivative is not available. Its contribution is '
187
196
  'not included in the response function.')
188
197
  omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, mol.spin)
189
198
 
190
199
  add_hf_(a, b, hyb)
200
+ if omega != 0: # For RSH
201
+ with mol.with_range_coulomb(omega):
202
+ eri_aa = ao2mo.general(mol, [orbo_a,mo_a,mo_a,mo_a], compact=False)
203
+ eri_bb = ao2mo.general(mol, [orbo_b,mo_b,mo_b,mo_b], compact=False)
204
+ eri_aa = eri_aa.reshape(nocc_a,nmo_a,nmo_a,nmo_a)
205
+ eri_bb = eri_bb.reshape(nocc_b,nmo_b,nmo_b,nmo_b)
206
+ a_aa, a_ab, a_bb = a
207
+ b_aa, b_ab, b_bb = b
208
+ k_fac = alpha - hyb
209
+ a_aa -= numpy.einsum('ijba->iajb', eri_aa[:nocc_a,:nocc_a,nocc_a:,nocc_a:]) * k_fac
210
+ b_aa -= numpy.einsum('jaib->iajb', eri_aa[:nocc_a,nocc_a:,:nocc_a,nocc_a:]) * k_fac
211
+ a_bb -= numpy.einsum('ijba->iajb', eri_bb[:nocc_b,:nocc_b,nocc_b:,nocc_b:]) * k_fac
212
+ b_bb -= numpy.einsum('jaib->iajb', eri_bb[:nocc_b,nocc_b:,:nocc_b,nocc_b:]) * k_fac
191
213
 
192
214
  xctype = ni._xc_type(mf.xc)
193
215
  dm0 = mf.make_rdm1(mo_coeff, mo_occ)
@@ -508,8 +530,8 @@ def analyze(tdobj, verbose=None):
508
530
  log.note('Excited State %3d: %12.5f eV %9.2f nm f=%.4f',
509
531
  i+1, e_ev[i], wave_length[i], f_oscillator[i])
510
532
  else:
511
- wfnsyma = rhf.analyze_wfnsym(tdobj, x_syma, x[0])
512
- wfnsymb = rhf.analyze_wfnsym(tdobj, x_symb, x[1])
533
+ wfnsyma = rhf._analyze_wfnsym(tdobj, x_syma, x[0])
534
+ wfnsymb = rhf._analyze_wfnsym(tdobj, x_symb, x[1])
513
535
  if wfnsyma == wfnsymb:
514
536
  wfnsym = wfnsyma
515
537
  else:
@@ -563,8 +585,8 @@ def _contract_multipole(tdobj, ints, hermi=True, xy=None):
563
585
  orbo_b = mo_coeff[1][:,mo_occ[1]==1]
564
586
  orbv_b = mo_coeff[1][:,mo_occ[1]==0]
565
587
 
566
- ints_a = numpy.einsum('...pq,pi,qj->...ij', ints, orbo_a.conj(), orbv_a)
567
- ints_b = numpy.einsum('...pq,pi,qj->...ij', ints, orbo_b.conj(), orbv_b)
588
+ ints_a = numpy.einsum('...pq,pi,qj->...ij', ints, orbo_a, orbv_a.conj())
589
+ ints_b = numpy.einsum('...pq,pi,qj->...ij', ints, orbo_b, orbv_b.conj())
568
590
  pol = [(numpy.einsum('...ij,ij->...', ints_a, x[0]) +
569
591
  numpy.einsum('...ij,ij->...', ints_b, x[1])) for x,y in xy]
570
592
  pol = numpy.array(pol)
@@ -606,7 +628,7 @@ class TDA(TDBase):
606
628
  mf = self._scf
607
629
  return gen_tda_hop(mf, wfnsym=self.wfnsym)
608
630
 
609
- def init_guess(self, mf, nstates=None, wfnsym=None):
631
+ def init_guess(self, mf, nstates=None, wfnsym=None, return_symmetry=False):
610
632
  if nstates is None: nstates = self.nstates
611
633
  if wfnsym is None: wfnsym = self.wfnsym
612
634
 
@@ -617,30 +639,42 @@ class TDA(TDBase):
617
639
  occidxb = numpy.where(mo_occ[1]>0)[0]
618
640
  viridxa = numpy.where(mo_occ[0]==0)[0]
619
641
  viridxb = numpy.where(mo_occ[1]==0)[0]
620
- e_ia_a = (mo_energy[0][viridxa,None] - mo_energy[0][occidxa]).T
621
- e_ia_b = (mo_energy[1][viridxb,None] - mo_energy[1][occidxb]).T
622
-
623
- if wfnsym is not None and mol.symmetry:
624
- if isinstance(wfnsym, str):
625
- wfnsym = symm.irrep_name2id(mol.groupname, wfnsym)
626
- orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mf.mo_coeff)
627
- wfnsym = wfnsym % 10 # convert to D2h subgroup
628
- orbsyma_in_d2h = numpy.asarray(orbsyma) % 10
629
- orbsymb_in_d2h = numpy.asarray(orbsymb) % 10
630
- e_ia_a[(orbsyma_in_d2h[occidxa,None] ^ orbsyma_in_d2h[viridxa]) != wfnsym] = 1e99
631
- e_ia_b[(orbsymb_in_d2h[occidxb,None] ^ orbsymb_in_d2h[viridxb]) != wfnsym] = 1e99
632
-
633
- e_ia = numpy.hstack((e_ia_a.ravel(), e_ia_b.ravel()))
634
- nov = e_ia.size
642
+ e_ia_a = mo_energy[0][viridxa] - mo_energy[0][occidxa,None]
643
+ e_ia_b = mo_energy[1][viridxb] - mo_energy[1][occidxb,None]
644
+ nov = e_ia_a.size + e_ia_b.size
635
645
  nstates = min(nstates, nov)
636
- e_threshold = numpy.sort(e_ia)[nstates-1]
646
+
647
+ if (wfnsym is not None or return_symmetry) and mf.mol.symmetry:
648
+ x_sym_a, x_sym_b = _get_x_sym_table(mf)
649
+ if wfnsym is not None:
650
+ if isinstance(wfnsym, str):
651
+ wfnsym = symm.irrep_name2id(mol.groupname, wfnsym)
652
+ wfnsym = wfnsym % 10 # convert to D2h subgroup
653
+ e_ia_a[x_sym_a != wfnsym] = 1e99
654
+ e_ia_b[x_sym_b != wfnsym] = 1e99
655
+ nov_allowed = (numpy.count_nonzero(x_sym_a == wfnsym) +
656
+ numpy.count_nonzero(x_sym_b == wfnsym))
657
+ nstates = min(nstates, nov_allowed)
658
+
659
+ e_ia = numpy.append(e_ia_a.ravel(), e_ia_b.ravel())
660
+ # Find the nstates-th lowest energy gap
661
+ e_threshold = numpy.partition(e_ia, nstates-1)[nstates-1]
637
662
  e_threshold += self.deg_eia_thresh
638
663
 
639
664
  idx = numpy.where(e_ia <= e_threshold)[0]
640
665
  x0 = numpy.zeros((idx.size, nov))
641
666
  for i, j in enumerate(idx):
642
667
  x0[i, j] = 1 # Koopmans' excitations
643
- return x0
668
+
669
+ if return_symmetry:
670
+ if mf.mol.symmetry:
671
+ x_sym = numpy.append(x_sym_a.ravel(), x_sym_b.ravel())
672
+ x0sym = x_sym[idx]
673
+ else:
674
+ x0sym = None
675
+ return x0, x0sym
676
+ else:
677
+ return x0
644
678
 
645
679
  def kernel(self, x0=None, nstates=None):
646
680
  '''TDA diagonalization solver
@@ -653,6 +687,7 @@ class TDA(TDBase):
653
687
  else:
654
688
  self.nstates = nstates
655
689
  log = logger.Logger(self.stdout, self.verbose)
690
+ mol = self.mol
656
691
 
657
692
  vind, hdiag = self.gen_vind(self._scf)
658
693
  precond = self.get_precond(hdiag)
@@ -661,16 +696,19 @@ class TDA(TDBase):
661
696
  idx = numpy.where(w > self.positive_eig_threshold)[0]
662
697
  return w[idx], v[:,idx], idx
663
698
 
699
+ x0sym = None
664
700
  if x0 is None:
665
- x0 = self.init_guess(self._scf, self.nstates)
666
-
667
- self.converged, self.e, x1 = \
668
- lib.davidson1(vind, x0, precond,
669
- tol=self.conv_tol,
670
- nroots=nstates, lindep=self.lindep,
671
- max_cycle=self.max_cycle,
672
- max_space=self.max_space, pick=pickeig,
673
- verbose=log)
701
+ x0, x0sym = self.init_guess(
702
+ self._scf, self.nstates, return_symmetry=True)
703
+ elif mol.symmetry:
704
+ x_sym_a, x_sym_b = _get_x_sym_table(self._scf)
705
+ x_sym = numpy.append(x_sym_a.ravel(), x_sym_b.ravel())
706
+ x0sym = [rhf._guess_wfnsym_id(self, x_sym, x) for x in x0]
707
+
708
+ self.converged, self.e, x1 = lr_eigh(
709
+ vind, x0, precond, tol_residual=self.conv_tol, lindep=self.lindep,
710
+ nroots=nstates, x0sym=x0sym, pick=pickeig, max_cycle=self.max_cycle,
711
+ max_memory=self.max_memory, verbose=log)
674
712
 
675
713
  nmo = self._scf.mo_occ[0].size
676
714
  nocca = (self._scf.mo_occ[0]>0).sum()
@@ -698,12 +736,11 @@ CIS = TDA
698
736
  def gen_tdhf_operation(mf, fock_ao=None, singlet=True, wfnsym=None):
699
737
  '''Generate function to compute
700
738
 
701
- [ A B][X]
702
- [-B -A][Y]
739
+ [ A B ][X]
740
+ [-B* -A*][Y]
703
741
  '''
704
742
  mol = mf.mol
705
743
  mo_coeff = mf.mo_coeff
706
- assert (mo_coeff[0].dtype == numpy.double)
707
744
  mo_energy = mf.mo_energy
708
745
  mo_occ = mf.mo_occ
709
746
  nao, nmo = mo_coeff[0].shape
@@ -723,20 +760,15 @@ def gen_tdhf_operation(mf, fock_ao=None, singlet=True, wfnsym=None):
723
760
  if wfnsym is not None and mol.symmetry:
724
761
  if isinstance(wfnsym, str):
725
762
  wfnsym = symm.irrep_name2id(mol.groupname, wfnsym)
726
- orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mo_coeff)
727
763
  wfnsym = wfnsym % 10 # convert to D2h subgroup
728
- orbsyma_in_d2h = numpy.asarray(orbsyma) % 10
729
- orbsymb_in_d2h = numpy.asarray(orbsymb) % 10
730
- sym_forbida = (orbsyma_in_d2h[occidxa,None] ^ orbsyma_in_d2h[viridxa]) != wfnsym
731
- sym_forbidb = (orbsymb_in_d2h[occidxb,None] ^ orbsymb_in_d2h[viridxb]) != wfnsym
732
- sym_forbid = numpy.hstack((sym_forbida.ravel(), sym_forbidb.ravel()))
764
+ x_sym_a, x_sym_b = _get_x_sym_table(mf)
765
+ sym_forbid = numpy.append(x_sym_a.ravel(), x_sym_b.ravel()) != wfnsym
733
766
 
734
767
  e_ia_a = mo_energy[0][viridxa] - mo_energy[0][occidxa,None]
735
768
  e_ia_b = mo_energy[1][viridxb] - mo_energy[1][occidxb,None]
736
769
  e_ia = hdiag = numpy.hstack((e_ia_a.ravel(), e_ia_b.ravel()))
737
770
  if wfnsym is not None and mol.symmetry:
738
771
  hdiag[sym_forbid] = 0
739
- hdiag = numpy.hstack((hdiag, -hdiag))
740
772
 
741
773
  mem_now = lib.current_memory()[0]
742
774
  max_memory = max(2000, mf.max_memory*.8-mem_now)
@@ -755,35 +787,33 @@ def gen_tdhf_operation(mf, fock_ao=None, singlet=True, wfnsym=None):
755
787
  xb = xs[:,nocca*nvira:].reshape(nz,noccb,nvirb)
756
788
  ya = ys[:,:nocca*nvira].reshape(nz,nocca,nvira)
757
789
  yb = ys[:,nocca*nvira:].reshape(nz,noccb,nvirb)
758
- # dms = AX + BY
759
- dmsa = lib.einsum('xov,qv,po->xpq', xa, orbva.conj(), orboa)
760
- dmsb = lib.einsum('xov,qv,po->xpq', xb, orbvb.conj(), orbob)
761
- dmsa += lib.einsum('xov,pv,qo->xpq', ya, orbva, orboa.conj())
762
- dmsb += lib.einsum('xov,pv,qo->xpq', yb, orbvb, orbob.conj())
763
-
790
+ dmsa = lib.einsum('xov,pv,qo->xpq', xa, orbva, orboa.conj())
791
+ dmsb = lib.einsum('xov,pv,qo->xpq', xb, orbvb, orbob.conj())
792
+ dmsa += lib.einsum('xov,qv,po->xpq', ya, orbva.conj(), orboa)
793
+ dmsb += lib.einsum('xov,qv,po->xpq', yb, orbvb.conj(), orbob)
764
794
  v1ao = vresp(numpy.asarray((dmsa,dmsb)))
765
-
766
- v1aov = lib.einsum('xpq,po,qv->xov', v1ao[0], orboa.conj(), orbva)
767
- v1avo = lib.einsum('xpq,qo,pv->xov', v1ao[0], orboa, orbva.conj())
768
- v1bov = lib.einsum('xpq,po,qv->xov', v1ao[1], orbob.conj(), orbvb)
769
- v1bvo = lib.einsum('xpq,qo,pv->xov', v1ao[1], orbob, orbvb.conj())
770
-
771
- v1ov = xs * e_ia # AX
772
- v1vo = ys * e_ia # AY
773
- v1ov[:,:nocca*nvira] += v1aov.reshape(nz,-1)
774
- v1vo[:,:nocca*nvira] += v1avo.reshape(nz,-1)
775
- v1ov[:,nocca*nvira:] += v1bov.reshape(nz,-1)
776
- v1vo[:,nocca*nvira:] += v1bvo.reshape(nz,-1)
795
+ v1a_top = lib.einsum('xpq,qo,pv->xov', v1ao[0], orboa, orbva.conj())
796
+ v1b_top = lib.einsum('xpq,qo,pv->xov', v1ao[1], orbob, orbvb.conj())
797
+ v1a_bot = lib.einsum('xpq,po,qv->xov', v1ao[0], orboa.conj(), orbva)
798
+ v1b_bot = lib.einsum('xpq,po,qv->xov', v1ao[1], orbob.conj(), orbvb)
799
+
800
+ v1_top = xs * e_ia # AX
801
+ v1_bot = ys * e_ia # AY
802
+ v1_top[:,:nocca*nvira] += v1a_top.reshape(nz,-1)
803
+ v1_bot[:,:nocca*nvira] += v1a_bot.reshape(nz,-1)
804
+ v1_top[:,nocca*nvira:] += v1b_top.reshape(nz,-1)
805
+ v1_bot[:,nocca*nvira:] += v1b_bot.reshape(nz,-1)
777
806
  if wfnsym is not None and mol.symmetry:
778
- v1ov[:,sym_forbid] = 0
779
- v1vo[:,sym_forbid] = 0
780
- hx = numpy.hstack((v1ov, -v1vo))
807
+ v1_top[:,sym_forbid] = 0
808
+ v1_bot[:,sym_forbid] = 0
809
+ hx = numpy.hstack((v1_top, -v1_bot))
781
810
  return hx
782
811
 
812
+ hdiag = numpy.hstack((hdiag, -hdiag))
783
813
  return vind, hdiag
784
814
 
785
815
 
786
- class TDHF(TDA):
816
+ class TDHF(TDBase):
787
817
 
788
818
  singlet = None
789
819
 
@@ -791,16 +821,22 @@ class TDHF(TDA):
791
821
  def gen_vind(self, mf=None):
792
822
  if mf is None:
793
823
  mf = self._scf
794
- return gen_tdhf_operation(mf, singlet=self.singlet, wfnsym=self.wfnsym)
824
+ return gen_tdhf_operation(mf, None, self.singlet, self.wfnsym)
795
825
 
796
- def init_guess(self, mf, nstates=None, wfnsym=None):
797
- x0 = TDA.init_guess(self, mf, nstates, wfnsym)
798
- y0 = numpy.zeros_like(x0)
799
- return numpy.asarray(numpy.block([[x0, y0], [y0, x0.conj()]]))
826
+ def init_guess(self, mf, nstates=None, wfnsym=None, return_symmetry=False):
827
+ if return_symmetry:
828
+ x0, x0sym = TDA.init_guess(self, mf, nstates, wfnsym, return_symmetry)
829
+ y0 = numpy.zeros_like(x0)
830
+ return numpy.hstack([x0, y0]), x0sym
831
+ else:
832
+ x0 = TDA.init_guess(self, mf, nstates, wfnsym, return_symmetry)
833
+ y0 = numpy.zeros_like(x0)
834
+ return numpy.hstack([x0, y0])
800
835
 
801
836
  def kernel(self, x0=None, nstates=None):
802
837
  '''TDHF diagonalization with non-Hermitian eigenvalue solver
803
838
  '''
839
+ log = logger.new_logger(self)
804
840
  cpu0 = (logger.process_clock(), logger.perf_counter())
805
841
  self.check_sanity()
806
842
  self.dump_flags()
@@ -808,55 +844,67 @@ class TDHF(TDA):
808
844
  nstates = self.nstates
809
845
  else:
810
846
  self.nstates = nstates
847
+ mol = self.mol
811
848
 
812
- log = logger.Logger(self.stdout, self.verbose)
849
+ real_system = True
850
+ # handle single kpt PBC SCF
851
+ if getattr(self._scf, 'kpt', None) is not None:
852
+ from pyscf.pbc.lib.kpts_helper import gamma_point
853
+ real_system = (gamma_point(self._scf.kpt) and
854
+ self._scf.mo_coeff[0].dtype == numpy.double)
855
+
856
+ real_eig_solver = real_system
813
857
 
814
858
  vind, hdiag = self.gen_vind(self._scf)
815
859
  precond = self.get_precond(hdiag)
816
-
817
- # We only need positive eigenvalues
818
- def pickeig(w, v, nroots, envs):
819
- realidx = numpy.where((abs(w.imag) < REAL_EIG_THRESHOLD) &
820
- (w.real > self.positive_eig_threshold))[0]
821
- return lib.linalg_helper._eigs_cmplx2real(w, v, realidx,
822
- real_eigenvectors=True)
823
-
860
+ if real_eig_solver:
861
+ eig = real_eig
862
+ pickeig = None
863
+ else:
864
+ eig = lr_eig
865
+ # We only need positive eigenvalues
866
+ def pickeig(w, v, nroots, envs):
867
+ realidx = numpy.where((abs(w.imag) < REAL_EIG_THRESHOLD) &
868
+ (w.real > self.positive_eig_threshold))[0]
869
+ return lib.linalg_helper._eigs_cmplx2real(w, v, realidx, real_system)
870
+
871
+ x0sym = None
824
872
  if x0 is None:
825
- x0 = self.init_guess(self._scf, self.nstates)
826
-
827
- self.converged, w, x1 = \
828
- lib.davidson_nosym1(vind, x0, precond,
829
- tol=self.conv_tol,
830
- nroots=nstates, lindep=self.lindep,
831
- max_cycle=self.max_cycle,
832
- max_space=self.max_space, pick=pickeig,
833
- verbose=log)
873
+ x0, x0sym = self.init_guess(
874
+ self._scf, self.nstates, return_symmetry=True)
875
+ elif mol.symmetry:
876
+ x_sym_a, x_sym_b = _get_x_sym_table(self._scf)
877
+ x_sym = y_sym = numpy.append(x_sym_a.ravel(), x_sym_b.ravel())
878
+ x_sym = numpy.append(x_sym, y_sym)
879
+ x0sym = [rhf._guess_wfnsym_id(self, x_sym, x) for x in x0]
880
+
881
+ self.converged, self.e, x1 = eig(
882
+ vind, x0, precond, tol_residual=self.conv_tol, lindep=self.lindep,
883
+ nroots=nstates, x0sym=x0sym, pick=pickeig, max_cycle=self.max_cycle,
884
+ max_memory=self.max_memory, verbose=log)
834
885
 
835
886
  nmo = self._scf.mo_occ[0].size
836
- nocca = (self._scf.mo_occ[0]>0).sum()
837
- noccb = (self._scf.mo_occ[1]>0).sum()
887
+ nocca, noccb = self._scf.nelec
838
888
  nvira = nmo - nocca
839
889
  nvirb = nmo - noccb
840
- e = []
841
890
  xy = []
842
891
  for i, z in enumerate(x1):
843
- x, y = z.reshape(2,-1)
892
+ x, y = z.reshape(2, -1)
844
893
  norm = lib.norm(x)**2 - lib.norm(y)**2
845
- if norm > 0:
846
- norm = 1/numpy.sqrt(norm)
847
- e.append(w[i])
848
- xy.append(((x[:nocca*nvira].reshape(nocca,nvira) * norm, # X_alpha
849
- x[nocca*nvira:].reshape(noccb,nvirb) * norm), # X_beta
850
- (y[:nocca*nvira].reshape(nocca,nvira) * norm, # Y_alpha
851
- y[nocca*nvira:].reshape(noccb,nvirb) * norm)))# Y_beta
852
- self.e = numpy.array(e)
894
+ if norm < 0:
895
+ log.warn('TDDFT amplitudes |X| smaller than |Y|')
896
+ norm = abs(norm)**-.5
897
+ xy.append(((x[:nocca*nvira].reshape(nocca,nvira) * norm, # X_alpha
898
+ x[nocca*nvira:].reshape(noccb,nvirb) * norm), # X_beta
899
+ (y[:nocca*nvira].reshape(nocca,nvira) * norm, # Y_alpha
900
+ y[nocca*nvira:].reshape(noccb,nvirb) * norm)))# Y_beta
853
901
  self.xy = xy
854
902
 
855
903
  if self.chkfile:
856
904
  lib.chkfile.save(self.chkfile, 'tddft/e', self.e)
857
905
  lib.chkfile.save(self.chkfile, 'tddft/xy', self.xy)
858
906
 
859
- log.timer('TDDFT', *cpu0)
907
+ log.timer('TDHF/TDDFT', *cpu0)
860
908
  self._finalize()
861
909
  return self.e, self.xy
862
910