pyscf 2.6.2__py3-none-macosx_11_0_arm64.whl → 2.7.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 (244) 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/outcore.py +6 -4
  20. pyscf/cc/__init__.py +21 -3
  21. pyscf/cc/bccd.py +0 -46
  22. pyscf/cc/ccsd.py +16 -8
  23. pyscf/cc/uccsd.py +1 -1
  24. pyscf/data/elements.py +1 -1
  25. pyscf/df/__init__.py +2 -1
  26. pyscf/df/addons.py +79 -51
  27. pyscf/df/autoaux.py +191 -0
  28. pyscf/df/df.py +5 -1
  29. pyscf/df/grad/casscf.py +0 -41
  30. pyscf/df/hessian/rhf.py +2 -10
  31. pyscf/df/hessian/rks.py +1 -7
  32. pyscf/df/hessian/uhf.py +3 -13
  33. pyscf/df/hessian/uks.py +1 -8
  34. pyscf/df/incore.py +17 -5
  35. pyscf/dft/dks.py +1 -1
  36. pyscf/dft/libxc.py +65 -639
  37. pyscf/dft/numint.py +7 -3
  38. pyscf/dft/radi.py +39 -5
  39. pyscf/dft/rks.py +1 -1
  40. pyscf/dft/xc_deriv.py +1 -1
  41. pyscf/dft/xcfun.py +53 -2
  42. pyscf/eph/eph_fd.py +1 -1
  43. pyscf/eph/rhf.py +6 -36
  44. pyscf/eph/rks.py +0 -4
  45. pyscf/eph/uhf.py +1 -7
  46. pyscf/eph/uks.py +1 -7
  47. pyscf/fci/addons.py +117 -2
  48. pyscf/fci/cistring.py +1 -1
  49. pyscf/fci/direct_nosym.py +3 -3
  50. pyscf/fci/direct_spin0_symm.py +22 -43
  51. pyscf/fci/direct_spin1.py +65 -9
  52. pyscf/fci/direct_spin1_symm.py +49 -14
  53. pyscf/fci/direct_uhf.py +4 -4
  54. pyscf/fci/selected_ci_symm.py +1 -1
  55. pyscf/grad/lagrange.py +11 -3
  56. pyscf/grad/mp2.py +1 -1
  57. pyscf/grad/sacasscf.py +1 -1
  58. pyscf/grad/tdrks.py +1 -1
  59. pyscf/gto/basis/__init__.py +7 -0
  60. pyscf/gto/basis/bse.py +68 -15
  61. pyscf/gto/basis/parse_cp2k_pp.py +1 -1
  62. pyscf/gto/basis/parse_nwchem.py +1 -1
  63. pyscf/gto/basis/parse_nwchem_ecp.py +2 -1
  64. pyscf/gto/basis/sap_grasp_large.dat +2438 -0
  65. pyscf/gto/basis/sap_grasp_small.dat +1434 -0
  66. pyscf/gto/mole.py +99 -44
  67. pyscf/gw/gw_ac.py +2 -2
  68. pyscf/gw/gw_cd.py +2 -2
  69. pyscf/gw/rpa.py +2 -2
  70. pyscf/gw/ugw_ac.py +2 -2
  71. pyscf/gw/urpa.py +1 -1
  72. pyscf/hessian/rhf.py +30 -128
  73. pyscf/hessian/rks.py +1 -6
  74. pyscf/hessian/uhf.py +28 -138
  75. pyscf/hessian/uks.py +1 -8
  76. pyscf/lib/ao2mo/nr_ao2mo.c +1 -1
  77. pyscf/lib/ao2mo/nrr_ao2mo.c +1 -1
  78. pyscf/lib/ao2mo/r_ao2mo.c +1 -1
  79. pyscf/lib/cc/ccsd_pack.c +1 -1
  80. pyscf/lib/cc/ccsd_t.c +6 -6
  81. pyscf/lib/cc/uccsd_t.c +4 -4
  82. pyscf/lib/deps/include/XCFun/XCFunExport.h +1 -0
  83. pyscf/lib/dft/grid_common.c +1 -1
  84. pyscf/lib/dft/libxc_itrf.c +4 -1
  85. pyscf/lib/dft/xcfun_itrf.c +1 -1
  86. pyscf/lib/diis.py +1 -1
  87. pyscf/lib/exceptions.py +3 -0
  88. pyscf/lib/gto/fill_grids_int2c.c +11 -9
  89. pyscf/lib/gto/fill_int2e.c +7 -5
  90. pyscf/lib/gto/fill_r_4c.c +1 -1
  91. pyscf/lib/gto/ft_ao.c +1 -1
  92. pyscf/lib/gto/ft_ao.h +1 -1
  93. pyscf/lib/gto/gto.h +2 -2
  94. pyscf/lib/gto/nr_ecp.c +3 -2
  95. pyscf/lib/libagf2.dylib +0 -0
  96. pyscf/lib/libao2mo.dylib +0 -0
  97. pyscf/lib/libcc.dylib +0 -0
  98. pyscf/lib/libcgto.dylib +0 -0
  99. pyscf/lib/libcvhf.dylib +0 -0
  100. pyscf/lib/libdft.dylib +0 -0
  101. pyscf/lib/libfci.dylib +0 -0
  102. pyscf/lib/libmcscf.dylib +0 -0
  103. pyscf/lib/libnp_helper.dylib +0 -0
  104. pyscf/lib/libpbc.dylib +0 -0
  105. pyscf/lib/libri.dylib +0 -0
  106. pyscf/lib/libxc_itrf.dylib +0 -0
  107. pyscf/lib/libxcfun_itrf.dylib +0 -0
  108. pyscf/lib/linalg_helper.py +112 -192
  109. pyscf/lib/mcscf/fci_contract.c +2 -2
  110. pyscf/lib/misc.py +47 -14
  111. pyscf/lib/numpy_helper.py +1 -1
  112. pyscf/lib/pbc/nr_ecp.c +10 -3
  113. pyscf/lib/pbc/pbc.h +1 -1
  114. pyscf/lib/vhf/nr_sgx_direct.c +8 -6
  115. pyscf/lib/vhf/optimizer.c +2 -2
  116. pyscf/lo/iao.py +1 -1
  117. pyscf/lo/ibo.py +3 -3
  118. pyscf/lo/pipek_jacobi.py +1 -1
  119. pyscf/mcscf/__init__.py +2 -2
  120. pyscf/mcscf/addons.py +3 -3
  121. pyscf/mcscf/apc.py +2 -2
  122. pyscf/mcscf/casci.py +8 -6
  123. pyscf/mcscf/chkfile.py +70 -41
  124. pyscf/mcscf/dmet_cas.py +2 -2
  125. pyscf/mcscf/mc1step.py +62 -38
  126. pyscf/mcscf/newton_casscf.py +5 -5
  127. pyscf/mcscf/ucasci.py +1 -1
  128. pyscf/mcscf/umc1step.py +44 -25
  129. pyscf/md/integrators.py +3 -3
  130. pyscf/mp/mp2.py +6 -5
  131. pyscf/mp/ump2.py +7 -6
  132. pyscf/pbc/adc/kadc_rhf.py +1 -1
  133. pyscf/pbc/adc/kadc_rhf_amplitudes.py +2 -2
  134. pyscf/pbc/ao2mo/eris.py +1 -1
  135. pyscf/pbc/cc/kccsd_rhf.py +3 -3
  136. pyscf/pbc/cc/kccsd_t_rhf.py +2 -2
  137. pyscf/pbc/ci/kcis_rhf.py +2 -2
  138. pyscf/pbc/df/aft.py +2 -2
  139. pyscf/pbc/df/aft_ao2mo.py +1 -1
  140. pyscf/pbc/df/df.py +84 -11
  141. pyscf/pbc/df/df_jk.py +2 -1
  142. pyscf/pbc/df/fft.py +6 -2
  143. pyscf/pbc/df/fft_ao2mo.py +4 -0
  144. pyscf/pbc/df/fft_jk.py +11 -3
  145. pyscf/pbc/df/ft_ao.py +4 -3
  146. pyscf/pbc/df/gdf_builder.py +5 -4
  147. pyscf/pbc/df/incore.py +1 -1
  148. pyscf/pbc/df/mdf.py +6 -3
  149. pyscf/pbc/df/rsdf.py +2 -2
  150. pyscf/pbc/df/rsdf_builder.py +11 -6
  151. pyscf/pbc/df/rsdf_helper.py +1 -1
  152. pyscf/pbc/dft/cdft.py +5 -5
  153. pyscf/pbc/dft/multigrid/multigrid.py +19 -26
  154. pyscf/pbc/dft/multigrid/multigrid_pair.py +1 -1
  155. pyscf/pbc/dft/multigrid/pp.py +1 -1
  156. pyscf/pbc/dft/numint.py +30 -21
  157. pyscf/pbc/eph/eph_fd.py +1 -1
  158. pyscf/pbc/geomopt/geometric_solver.py +1 -1
  159. pyscf/pbc/gto/cell.py +37 -19
  160. pyscf/pbc/gto/ecp.py +12 -12
  161. pyscf/pbc/gto/eval_gto.py +2 -2
  162. pyscf/pbc/gto/pseudo/pp.py +1 -1
  163. pyscf/pbc/gw/krgw_ac.py +4 -4
  164. pyscf/pbc/gw/krgw_cd.py +4 -4
  165. pyscf/pbc/gw/kugw_ac.py +3 -3
  166. pyscf/pbc/lib/kpts_helper.py +4 -3
  167. pyscf/pbc/lib/linalg_helper.py +1 -1
  168. pyscf/pbc/mp/kmp2.py +1 -1
  169. pyscf/pbc/mpitools/mpi.py +1 -1
  170. pyscf/pbc/scf/addons.py +15 -11
  171. pyscf/pbc/scf/cphf.py +1 -1
  172. pyscf/pbc/scf/ghf.py +1 -1
  173. pyscf/pbc/scf/hf.py +21 -24
  174. pyscf/pbc/scf/kghf.py +33 -29
  175. pyscf/pbc/scf/khf.py +71 -26
  176. pyscf/pbc/scf/krohf.py +5 -7
  177. pyscf/pbc/scf/kuhf.py +53 -22
  178. pyscf/pbc/scf/rsjk.py +13 -9
  179. pyscf/pbc/scf/scfint.py +1 -1
  180. pyscf/pbc/scf/stability.py +1 -1
  181. pyscf/pbc/scf/uhf.py +3 -1
  182. pyscf/pbc/symm/symmetry.py +2 -2
  183. pyscf/pbc/tdscf/kproxy.py +1 -1
  184. pyscf/pbc/tdscf/kproxy_supercell.py +2 -2
  185. pyscf/pbc/tdscf/krhf.py +215 -133
  186. pyscf/pbc/tdscf/krhf_slow_supercell.py +1 -1
  187. pyscf/pbc/tdscf/krks.py +1 -45
  188. pyscf/pbc/tdscf/kuhf.py +58 -105
  189. pyscf/pbc/tdscf/kuks.py +0 -56
  190. pyscf/pbc/tdscf/proxy.py +1 -1
  191. pyscf/pbc/tdscf/rhf.py +111 -3
  192. pyscf/pbc/tdscf/rks.py +2 -1
  193. pyscf/pbc/tdscf/uhf.py +203 -1
  194. pyscf/pbc/tdscf/uks.py +2 -1
  195. pyscf/pbc/tools/k2gamma.py +7 -4
  196. pyscf/pbc/tools/pbc.py +63 -56
  197. pyscf/pbc/tools/pyscf_ase.py +0 -1
  198. pyscf/pbc/tools/pywannier90.py +1 -1
  199. pyscf/qmmm/mm_mole.py +1 -1
  200. pyscf/scf/_response_functions.py +2 -2
  201. pyscf/scf/_vhf.py +14 -10
  202. pyscf/scf/addons.py +29 -15
  203. pyscf/scf/cphf.py +14 -52
  204. pyscf/scf/dhf.py +39 -10
  205. pyscf/scf/dispersion.py +9 -8
  206. pyscf/scf/ghf.py +25 -13
  207. pyscf/scf/ghf_symm.py +2 -2
  208. pyscf/scf/hf.py +245 -29
  209. pyscf/scf/rohf.py +37 -5
  210. pyscf/scf/stability.py +142 -112
  211. pyscf/scf/ucphf.py +21 -16
  212. pyscf/scf/uhf.py +95 -58
  213. pyscf/sgx/sgx.py +1 -1
  214. pyscf/sgx/sgx_jk.py +4 -4
  215. pyscf/solvent/_ddcosmo_tdscf_grad.py +1 -1
  216. pyscf/solvent/ddcosmo.py +1 -1
  217. pyscf/solvent/pol_embed.py +1 -1
  218. pyscf/soscf/ciah.py +1 -1
  219. pyscf/soscf/newton_ah.py +1 -1
  220. pyscf/symm/__init__.py +1 -1
  221. pyscf/symm/addons.py +5 -5
  222. pyscf/tdscf/_lr_eig.py +505 -0
  223. pyscf/tdscf/common_slow.py +1 -1
  224. pyscf/tdscf/dhf.py +41 -37
  225. pyscf/tdscf/dks.py +0 -4
  226. pyscf/tdscf/ghf.py +91 -71
  227. pyscf/tdscf/gks.py +16 -16
  228. pyscf/tdscf/proxy.py +2 -2
  229. pyscf/tdscf/rhf.py +143 -96
  230. pyscf/tdscf/rks.py +15 -14
  231. pyscf/tdscf/uhf.py +117 -70
  232. pyscf/tdscf/uks.py +17 -18
  233. pyscf/tools/fcidump.py +3 -0
  234. pyscf/x2c/sfx2c1e.py +1 -1
  235. pyscf/x2c/tdscf.py +4 -4
  236. pyscf/x2c/x2c.py +15 -11
  237. {pyscf-2.6.2.dist-info → pyscf-2.7.0.dist-info}/METADATA +24 -24
  238. {pyscf-2.6.2.dist-info → pyscf-2.7.0.dist-info}/NOTICE +3 -1
  239. {pyscf-2.6.2.dist-info → pyscf-2.7.0.dist-info}/RECORD +242 -240
  240. {pyscf-2.6.2.dist-info → pyscf-2.7.0.dist-info}/WHEEL +1 -1
  241. pyscf/dft/gen_libxc_param.py +0 -35
  242. pyscf/dft/gen_xcfun_param.py +0 -209
  243. {pyscf-2.6.2.dist-info → pyscf-2.7.0.dist-info}/LICENSE +0 -0
  244. {pyscf-2.6.2.dist-info → pyscf-2.7.0.dist-info}/top_level.txt +0 -0
pyscf/fci/direct_spin1.py CHANGED
@@ -50,7 +50,7 @@ from pyscf.fci import rdm
50
50
  from pyscf.fci import spin_op
51
51
  from pyscf.fci import addons
52
52
  from pyscf.fci.spin_op import contract_ss
53
- from pyscf.fci.addons import _unpack_nelec
53
+ from pyscf.fci.addons import _unpack_nelec, civec_spinless_repr
54
54
  from pyscf import __config__
55
55
 
56
56
  libfci = cistring.libfci
@@ -371,6 +371,46 @@ def make_rdm12(fcivec, norb, nelec, link_index=None, reorder=True):
371
371
  dm1, dm2 = rdm.reorder_rdm(dm1, dm2, inplace=True)
372
372
  return dm1, dm2
373
373
 
374
+ def make_rdm123(fcivec, norb, nelec, link_index=None, reorder=True):
375
+ '''Spin traced 1-, 2-, and 3-particle density matrices.'''
376
+ dm1, dm2, dm3 = rdm.make_dm123('FCI3pdm_kern_sf', fcivec, fcivec, norb, nelec)
377
+ if reorder:
378
+ dm1, dm2, dm3 = rdm.reorder_dm123(dm1, dm2, dm3, inplace=True)
379
+ return dm1, dm2, dm3
380
+
381
+ def make_rdm123s(fcivec, norb, nelec, link_index=None, reorder=True):
382
+ r'''Spin separated 1-, 2-, and 3-particle density matrices.
383
+
384
+ 1pdm[p,q] = :math:`\langle q_\alpha^\dagger p_\alpha \rangle +
385
+ \langle q_\beta^\dagger p_\beta \rangle`;
386
+ 2pdm[p,q,r,s] = :math:`\langle p_\alpha^\dagger r_\alpha^\dagger s_\alpha q_\alpha\rangle +
387
+ \langle p_\beta^\dagger r_\alpha^\dagger s_\alpha q_\beta\rangle +
388
+ \langle p_\alpha^\dagger r_\beta^\dagger s_\beta q_\alpha\rangle +
389
+ \langle p_\beta^\dagger r_\beta^\dagger s_\beta q_\beta\rangle`.
390
+ '''
391
+ if (not reorder):
392
+ raise NotImplementedError('reorder=False not currently supported')
393
+ ci_spinless = civec_spinless_repr([fcivec,], norb, [nelec,])
394
+ rdm1, rdm2, rdm3 = make_rdm123(ci_spinless, norb*2, (nelec[0]+nelec[1],0))
395
+
396
+ rdm1a = rdm1[:norb,:norb]
397
+ rdm1b = rdm1[norb:,norb:]
398
+ # assert np.allclose(rdm1a+rdm1b, rdm1)
399
+
400
+ rdm2aa = rdm2[:norb,:norb,:norb,:norb]
401
+ rdm2ab = rdm2[:norb,:norb,norb:,norb:]
402
+ rdm2bb = rdm2[norb:,norb:,norb:,norb:]
403
+ # assert np.allclose(rdm2aa+rdm2bb+rdm2ab+rdm2ab.transpose(2,3,0,1), rdm2)
404
+
405
+ rdm3aaa = rdm3[:norb,:norb,:norb,:norb,:norb,:norb]
406
+ rdm3aab = rdm3[:norb,:norb,:norb,:norb,norb:,norb:]
407
+ rdm3abb = rdm3[:norb,:norb,norb:,norb:,norb:,norb:]
408
+ rdm3bbb = rdm3[norb:,norb:,norb:,norb:,norb:,norb:]
409
+ # assert np.allclose(rdm3aaa+rdm3bbb+rdm3aab+rdm3aab.transpose(0,1,4,5,2,3)+\
410
+ # rdm3aab.transpose(4,5,0,1,2,3)+rdm3abb+rdm3abb.transpose(2,3,0,1,4,5)+rdm3abb.transpose(2,3,4,5,0,1), rdm3)
411
+ return (rdm1a, rdm1b), (rdm2aa, rdm2ab, rdm2bb), (rdm3aaa, rdm3aab, rdm3abb, rdm3bbb)
412
+
413
+
374
414
  def trans_rdm1s(cibra, ciket, norb, nelec, link_index=None):
375
415
  r'''Spin separated transition 1-particle density matrices.
376
416
  The return values include two density matrices: (alpha,alpha), (beta,beta).
@@ -440,8 +480,11 @@ def _get_init_guess(na, nb, nroots, hdiag, nelec):
440
480
  ci0 = []
441
481
  neleca, nelecb = _unpack_nelec(nelec)
442
482
  if neleca == nelecb and na == nb:
443
- hdiag = hdiag.reshape(na, na)
444
- addrs = numpy.argpartition(lib.pack_tril(hdiag), nroots-1)[:nroots]
483
+ hdiag = lib.pack_tril(hdiag.reshape(na, na))
484
+ if hdiag.size <= nroots:
485
+ addrs = numpy.arange(hdiag.size)
486
+ else:
487
+ addrs = numpy.argpartition(hdiag, nroots-1)[:nroots]
445
488
  for addr in addrs:
446
489
  addra = (int)((2*addr+.25)**.5 - .5 + 1e-7)
447
490
  addrb = addr - addra*(addra+1)//2
@@ -449,7 +492,10 @@ def _get_init_guess(na, nb, nroots, hdiag, nelec):
449
492
  x[addra,addrb] = 1
450
493
  ci0.append(x.ravel().view(FCIvector))
451
494
  else:
452
- addrs = numpy.argpartition(hdiag, nroots-1)[:nroots]
495
+ if hdiag.size <= nroots:
496
+ addrs = numpy.arange(hdiag.size)
497
+ else:
498
+ addrs = numpy.argpartition(hdiag, nroots-1)[:nroots]
453
499
  for addr in addrs:
454
500
  x = numpy.zeros((na*nb))
455
501
  x[addr] = 1
@@ -505,8 +551,8 @@ def kernel_ms1(fci, h1e, eri, norb, nelec, ci0=None, link_index=None,
505
551
  nroots: int
506
552
  Number of states to solve
507
553
  davidson_only: bool
508
- Whether to call subspace diagonlization (davidson solver) or do a
509
- full diagonlization (lapack eigh) for small systems
554
+ Whether to call subspace diagonalization (davidson solver) or do a
555
+ full diagonalization (lapack eigh) for small systems
510
556
  pspace_size: int
511
557
  Number of determinants as the threshold of "small systems",
512
558
  hop: function(c) => array_like_c
@@ -663,7 +709,7 @@ class FCIBase(lib.StreamObject):
663
709
  problems being solved by Davidson subspace algorithm. This flag
664
710
  should be enabled when initial guess is given or particular spin
665
711
  symmetry or point-group symmetry is required because the initial
666
- guess or symmetry are completely ignored in the direct diagonlization.
712
+ guess or symmetry are completely ignored in the direct diagonalization.
667
713
  pspace_size : int
668
714
  The dimension of Hamiltonian matrix over which Davidson iteration
669
715
  algorithm will be used for the eigenvalue problem. Default is 400.
@@ -710,8 +756,8 @@ class FCIBase(lib.StreamObject):
710
756
  # dependence basis in davidson diagonalization solver
711
757
  level_shift = getattr(__config__, 'fci_direct_spin1_FCI_level_shift', 1e-3)
712
758
 
713
- # force the diagonlization use davidson iteration. When the CI space
714
- # is small, the solver exactly diagonlizes the Hamiltonian. But this
759
+ # force the diagonalization use davidson iteration. When the CI space
760
+ # is small, the solver exactly diagonalizes the Hamiltonian. But this
715
761
  # solution will ignore the initial guess. Setting davidson_only can
716
762
  # enforce the solution on the initial guess state
717
763
  davidson_only = getattr(__config__, 'fci_direct_spin1_FCI_davidson_only', False)
@@ -884,6 +930,16 @@ class FCIBase(lib.StreamObject):
884
930
  nelec = _unpack_nelec(nelec, self.spin)
885
931
  return make_rdm12(fcivec, norb, nelec, link_index, reorder)
886
932
 
933
+ @lib.with_doc(make_rdm123s.__doc__)
934
+ def make_rdm123s(self, fcivec, norb, nelec, link_index=None, reorder=True):
935
+ nelec = _unpack_nelec(nelec, self.spin)
936
+ return make_rdm123s(fcivec, norb, nelec, link_index, reorder)
937
+
938
+ @lib.with_doc(make_rdm123.__doc__)
939
+ def make_rdm123(self, fcivec, norb, nelec, link_index=None, reorder=True):
940
+ nelec = _unpack_nelec(nelec, self.spin)
941
+ return make_rdm123(fcivec, norb, nelec, link_index, reorder)
942
+
887
943
  def make_rdm2(self, fcivec, norb, nelec, link_index=None, reorder=True):
888
944
  r'''Spin traced 2-particle density matrice
889
945
 
@@ -217,22 +217,28 @@ def _get_init_guess(airreps, birreps, nroots, hdiag, nelec, orbsym, wfnsym=0):
217
217
  neleca, nelecb = _unpack_nelec(nelec)
218
218
  na = len(airreps)
219
219
  nb = len(birreps)
220
- hdiag = hdiag.reshape(na,nb)
221
220
  sym_allowed = airreps[:,None] == wfnsym ^ birreps
222
221
  if neleca == nelecb and na == nb:
223
222
  idx = np.arange(na)
224
223
  sym_allowed[idx[:,None] < idx] = False
225
224
  idx_a, idx_b = np.where(sym_allowed)
226
225
 
226
+ hdiag = hdiag.reshape(na,nb)[idx_a,idx_b]
227
+ if hdiag.size <= nroots:
228
+ hdiag_indices = np.arange(hdiag.size)
229
+ else:
230
+ hdiag_indices = np.argpartition(hdiag, nroots-1)[:nroots]
231
+
227
232
  ci0 = []
228
- for k in np.argpartition(hdiag[idx_a,idx_b], nroots-1)[:nroots]:
233
+ for k in hdiag_indices:
229
234
  addra, addrb = idx_a[k], idx_b[k]
230
235
  x = np.zeros((na, nb))
231
236
  x[addra,addrb] = 1
232
237
  ci0.append(x.ravel().view(direct_spin1.FCIvector))
233
238
 
234
239
  if len(ci0) == 0:
235
- raise RuntimeError(f'Initial guess for symmetry {wfnsym} not found')
240
+ raise lib.exceptions.WfnSymmetryError(
241
+ f'Initial guess for symmetry {wfnsym} not found')
236
242
  return ci0
237
243
 
238
244
  def get_init_guess(norb, nelec, nroots, hdiag, orbsym, wfnsym=0):
@@ -248,13 +254,18 @@ def get_init_guess(norb, nelec, nroots, hdiag, orbsym, wfnsym=0):
248
254
  return _get_init_guess(airreps, birreps, nroots, hdiag, nelec, orbsym, wfnsym)
249
255
 
250
256
  ci0 = []
251
- for k in np.argpartition(hdiag, nroots-1)[:nroots]:
257
+ if hdiag.size <= nroots:
258
+ hdiag_indices = np.arange(hdiag.size)
259
+ else:
260
+ hdiag_indices = np.argpartition(hdiag, nroots-1)[:nroots]
261
+ for k in hdiag_indices:
252
262
  x = np.zeros_like(hdiag)
253
263
  x[k] = 1.
254
264
  ci0.append(x.ravel().view(direct_spin1.FCIvector))
255
265
 
256
266
  if len(ci0) == 0:
257
- raise RuntimeError(f'Initial guess for symmetry {wfnsym} not found')
267
+ raise lib.exceptions.WfnSymmetryError(
268
+ f'Initial guess for symmetry {wfnsym} not found')
258
269
  return ci0
259
270
 
260
271
  def _validate_degen_mapping(mapping, norb):
@@ -301,6 +312,13 @@ def get_init_guess_cyl_sym(norb, nelec, nroots, hdiag, orbsym, wfnsym=0):
301
312
  addra1, sign_a = _sv_associated_det(strsa[addra], degen_mapping)
302
313
  addrb1, sign_b = _sv_associated_det(strsb[addrb], degen_mapping)
303
314
  if wfnsym in (1, 4) and addra == addra1 and addrb == addrb1:
315
+ # Remove the A1 repr from initial guess.
316
+ # The product of two E reprs can produce A1, A2 and another E repr.
317
+ # addra == addra1 and addrb == addrb1 can be found in the A1 repr.
318
+ # However, this may also incorrectly remove the A2 repr, see the
319
+ # explanation in issue #2291.
320
+ # In this case, the direct_spin1_cyl_sym solver can be used to
321
+ # solve A2. See example mcscf/18-o2_spatial_spin_symmetry.py
304
322
  continue
305
323
  x = ca[:,None] * cb
306
324
 
@@ -339,7 +357,8 @@ def get_init_guess_cyl_sym(norb, nelec, nroots, hdiag, orbsym, wfnsym=0):
339
357
  break
340
358
 
341
359
  if len(ci0) == 0:
342
- raise RuntimeError(f'Initial guess for symmetry {wfnsym} not found')
360
+ raise lib.exceptions.WfnSymmetryError(
361
+ f'Initial guess for symmetry {wfnsym} not found')
343
362
  return ci0
344
363
 
345
364
  def _cyl_sym_csf2civec(strs, addr, orbsym, degen_mapping):
@@ -500,19 +519,34 @@ def _guess_wfnsym_cyl_sym(civec, strsa, strsb, orbsym):
500
519
  if wfn_momentum == 0:
501
520
  # For A1g and A1u, CI coefficient and its sigma_v associated one have
502
521
  # the same sign
503
- if (sign_a*sign_b * c_max[0,0].real * c_max[1,1].real > 1e-6 or
504
- sign_a*sign_b * c_max[0,0].imag * c_max[1,1].imag > 1e-6): # A1
522
+ if (sign_a*sign_b * c_max[0,0].real * c_max[1,1].real > 1e-4 or
523
+ sign_a*sign_b * c_max[0,0].imag * c_max[1,1].imag > 1e-4): # A1
505
524
  if wfn_ungerade:
506
525
  wfnsym = 5
507
526
  else:
508
527
  wfnsym = 0
509
- else:
528
+ elif (sign_a*sign_b * c_max[0,0].real * c_max[1,1].real < -1e-4 or
529
+ sign_a*sign_b * c_max[0,0].imag * c_max[1,1].imag < -1e-4): # A2
510
530
  # For A2g and A2u, CI coefficient and its sigma_v associated one
511
531
  # have opposite signs
512
532
  if wfn_ungerade:
513
533
  wfnsym = 4
514
534
  else:
515
535
  wfnsym = 1
536
+ elif abs(c_max[0,1] - c_max[1,0]) < 1e-4: # Off-diagonal terms only
537
+ # (E+)(E-') + (E-)(E+') => A1
538
+ if wfn_ungerade:
539
+ wfnsym = 5
540
+ else:
541
+ wfnsym = 0
542
+ elif abs(c_max[0,1] + c_max[1,0]) < 1e-4:
543
+ # (E+)(E-') - (E-)(E+') => A2
544
+ if wfn_ungerade:
545
+ wfnsym = 4
546
+ else:
547
+ wfnsym = 1
548
+ else:
549
+ raise RuntimeError('Symmetry broken wavefunction')
516
550
 
517
551
  elif wfn_momentum % 2 == 1:
518
552
  if abs(c_max[idx_a,idx_b].real) > 1e-6: # Ex
@@ -582,8 +616,9 @@ def guess_wfnsym(solver, norb, nelec, fcivec=None, orbsym=None, wfnsym=None, **k
582
616
  fcivec = fcivec[0]
583
617
  wfnsym1 = _guess_wfnsym_cyl_sym(fcivec, strsa, strsb, orbsym)
584
618
  if wfnsym1 != _id_wfnsym(solver, norb, nelec, orbsym, wfnsym):
585
- raise RuntimeError(f'Input wfnsym {wfnsym} is not consistent with '
586
- f'fcivec symmetry {wfnsym1}')
619
+ raise lib.exceptions.WfnSymmetryError(
620
+ f'Input wfnsym {wfnsym} is not consistent with '
621
+ f'fcivec symmetry {wfnsym1}')
587
622
  wfnsym = wfnsym1
588
623
  else:
589
624
  na, nb = strsa.size, strsb.size
@@ -601,8 +636,8 @@ def guess_wfnsym(solver, norb, nelec, fcivec=None, orbsym=None, wfnsym=None, **k
601
636
  if isinstance(fcivec, np.ndarray) and fcivec.ndim <= 2:
602
637
  fcivec = [fcivec]
603
638
  if all(abs(c.reshape(na, nb)[mask]).max() < 1e-5 for c in fcivec):
604
- raise RuntimeError('Input wfnsym {wfnsym} is not consistent with '
605
- 'fcivec coefficients')
639
+ raise lib.exceptions.WfnSymmetryError(
640
+ 'Input wfnsym {wfnsym} is not consistent with fcivec coefficients')
606
641
  return wfnsym
607
642
 
608
643
  def sym_allowed_indices(nelec, orbsym, wfnsym):
@@ -771,7 +806,7 @@ class FCISolver(direct_spin1.FCISolver):
771
806
  logger.debug(self, 'Num symmetry allowed elements %d',
772
807
  sum([x.size for x in self.sym_allowed_idx]))
773
808
  if s_idx.size == 0:
774
- raise RuntimeError(
809
+ raise lib.exceptions.WfnSymmetryError(
775
810
  f'Symmetry allowed determinants not found for wfnsym {wfnsym}')
776
811
 
777
812
  if wfnsym_ir > 7:
pyscf/fci/direct_uhf.py CHANGED
@@ -41,7 +41,7 @@ from pyscf.fci.spin_op import spin_square
41
41
 
42
42
  libfci = direct_spin1.libfci
43
43
 
44
- # When the spin-orbitals do not have the degeneracy on spacial part,
44
+ # When the spin-orbitals do not have the degeneracy on spatial part,
45
45
  # there is only one version of FCI which is close to _spin1 solver.
46
46
  # The inputs: h1e has two parts (h1e_a, h1e_b),
47
47
  # h2e has three parts (h2e_aa, h2e_ab, h2e_bb)
@@ -198,7 +198,7 @@ def pspace(h1e, eri, norb, nelec, hdiag=None, np=400):
198
198
  na = cistring.num_strings(norb, neleca)
199
199
  nb = cistring.num_strings(norb, nelecb)
200
200
  assert hdiag.size == na * nb
201
- if hdiag.size < np:
201
+ if hdiag.size <= np:
202
202
  addr = numpy.arange(hdiag.size)
203
203
  else:
204
204
  try:
@@ -245,14 +245,14 @@ def energy(h1e, eri, fcivec, norb, nelec, link_index=None):
245
245
  # dm_pq = <|p^+ q|>
246
246
  make_rdm1s = direct_spin1.make_rdm1s
247
247
 
248
- # spacial part of DM, dm_pq = <|p^+ q|>
248
+ # spatial part of DM, dm_pq = <|p^+ q|>
249
249
  def make_rdm1(fcivec, norb, nelec, link_index=None):
250
250
  raise ValueError('Spin trace for UHF-FCI density matrices.')
251
251
 
252
252
  make_rdm12s = direct_spin1.make_rdm12s
253
253
  trans_rdm1s = direct_spin1.trans_rdm1s
254
254
 
255
- # spacial part of DM
255
+ # spatial part of DM
256
256
  def trans_rdm1(cibra, ciket, norb, nelec, link_index=None):
257
257
  raise ValueError('Spin trace for UHF-FCI density matrices.')
258
258
 
@@ -178,7 +178,7 @@ class SelectedCI(selected_ci.SelectedCI):
178
178
  wfnsym = [addons._guess_wfnsym(c, strsa, strsb, orbsym)
179
179
  for c in fcivec]
180
180
  if any(wfnsym[0] != x for x in wfnsym):
181
- warnings.warn('Different wfnsym %s found in different CI vecotrs' % wfnsym)
181
+ warnings.warn('Different wfnsym %s found in different CI vectors' % wfnsym)
182
182
  wfnsym = wfnsym[0]
183
183
 
184
184
  else:
pyscf/grad/lagrange.py CHANGED
@@ -14,6 +14,7 @@
14
14
  # limitations under the License.
15
15
 
16
16
  import numpy as np
17
+ import scipy
17
18
  from scipy import linalg, optimize
18
19
  from scipy.sparse import linalg as sparse_linalg
19
20
  from pyscf import lib, __config__
@@ -126,9 +127,9 @@ class Gradients (rhf_grad.GradientsBase):
126
127
  prec_obj = sparse_linalg.LinearOperator ((self.nlag,self.nlag), matvec=precond,
127
128
  dtype=bvec.dtype)
128
129
  x0_guess = self.get_init_guess (bvec, Adiag, Aop, precond)
129
- Lvec, info_int = sparse_linalg.cg(Aop_obj, -bvec, x0=x0_guess,
130
- tol=self.conv_rtol, atol=self.conv_atol,
131
- maxiter=self.max_cycle, callback=my_call, M=prec_obj)
130
+ Lvec, info_int = _cg(Aop_obj, -bvec, x0=x0_guess,
131
+ tol=self.conv_rtol, atol=self.conv_atol,
132
+ maxiter=self.max_cycle, callback=my_call, M=prec_obj)
132
133
  logger.info (self, ('Lagrange multiplier determination {} after {} iterations\n'
133
134
  ' |geff| = {}, |Lvec| = {}').format (
134
135
  'converged' if info_int == 0 else 'not converged',
@@ -190,3 +191,10 @@ class LagPrec :
190
191
  Adiagd[abs(Adiagd)<1e-8] = 1e-8
191
192
  x /= Adiagd
192
193
  return x
194
+
195
+ if int (scipy.__version__.split('.')[1]) >= 14: # scipy 1.14
196
+ def _cg(A, b, x0=None, *, tol=1e-05, atol=0.0, maxiter=None, M=None, callback=None):
197
+ return sparse_linalg.cg(A, b, x0, rtol=tol, atol=atol, maxiter=maxiter,
198
+ M=M, callback=callback)
199
+ else:
200
+ _cg = sparse_linalg.cg
pyscf/grad/mp2.py CHANGED
@@ -42,7 +42,7 @@ def grad_elec(mp_grad, t2, atmlst=None, verbose=logger.INFO):
42
42
  doo, dvv = d1
43
43
  time1 = log.timer_debug1('rdm1 intermediates', *time0)
44
44
 
45
- # Set nocc, nvir for half-transformation of 2pdm. Frozen orbitals are exculded.
45
+ # Set nocc, nvir for half-transformation of 2pdm. Frozen orbitals are excluded.
46
46
  # nocc, nvir should be updated to include the frozen orbitals when proceeding
47
47
  # the 1-particle quantities later.
48
48
  mol = mp_grad.mol
pyscf/grad/sacasscf.py CHANGED
@@ -876,7 +876,7 @@ class SACASLagPrec (lagrange.LagPrec):
876
876
  except Exception as e:
877
877
  print (i, j, desort_spin)
878
878
  raise (e)
879
- assert (all ([i is not None for i in Mxci]))
879
+ assert (all (i is not None for i in Mxci))
880
880
  return Mxci
881
881
 
882
882
  mcscf.addons.StateAverageMCSCFSolver.Gradients = lib.class_as_method(Gradients)
pyscf/grad/tdrks.py CHANGED
@@ -307,7 +307,7 @@ def _contract_xc_kernel(td_grad, xc_code, dmvo, dmoo=None, with_vxc=True,
307
307
  rho *= .5
308
308
  rho = numpy.repeat(rho[numpy.newaxis], 2, axis=0)
309
309
  vxc, fxc, kxc = ni.eval_xc_eff(xc_code, rho, deriv, xctype=xctype)[1:]
310
- # fxc_t couples triplet excitation amplitues
310
+ # fxc_t couples triplet excitation amplitudes
311
311
  # 1/2 int (tia - tIA) fxc (tjb - tJB) = tia fxc_t tjb
312
312
  fxc_t = fxc[:,:,0] - fxc[:,:,1]
313
313
  fxc_t = fxc_t[0] - fxc_t[1]
@@ -413,6 +413,11 @@ PP_ALIAS = {
413
413
  'gthhfrev' : 'gth-hf-rev.dat' ,
414
414
  }
415
415
 
416
+ SAP_ALIAS = {
417
+ 'sapgraspsmall' : 'sap_grasp_small.dat',
418
+ 'sapgrasplarge' : 'sap_grasp_large.dat',
419
+ }
420
+
416
421
  def _is_pople_basis(basis):
417
422
  return (basis.startswith('631') or
418
423
  basis.startswith('321') or
@@ -603,6 +608,8 @@ def load(filename_or_basisname, symb, optimize=OPTIMIZE_CONTRACTION):
603
608
  basis_dir = _GTH_BASIS_DIR
604
609
  elif _is_pople_basis(name):
605
610
  basmod = _parse_pople_basis(name, symb)
611
+ elif name in SAP_ALIAS:
612
+ basmod = SAP_ALIAS[name]
606
613
  else:
607
614
  try:
608
615
  return parse_nwchem.parse(filename_or_basisname, symb,
pyscf/gto/basis/bse.py CHANGED
@@ -11,13 +11,16 @@ except ImportError:
11
11
  basis_set_exchange = None
12
12
 
13
13
 
14
- def _orbital_basis(basis):
14
+ def _orbital_basis(basis, make_general=False):
15
15
  '''Extracts the orbital basis from the BSE format in PySCF format'''
16
16
 
17
17
  r = {}
18
18
 
19
- basis = manip.make_general(basis, False, True)
20
- basis = sort.sort_basis(basis, False)
19
+ if make_general:
20
+ basis = manip.make_general(basis, False, use_copy=True)
21
+ basis = sort.sort_basis(basis, use_copy=False)
22
+ else:
23
+ basis = sort.sort_basis(basis, use_copy=True)
21
24
 
22
25
  # Elements for which we have electron basis
23
26
  electron_elements = [k for k, v in basis['elements'].items() if 'electron_shells' in v]
@@ -40,21 +43,29 @@ def _orbital_basis(basis):
40
43
  ncontr = len(coefficients)
41
44
  nprim = len(exponents)
42
45
  am = shell['angular_momentum']
43
- assert len(am) == 1
44
-
45
- shell_data = [am[0]]
46
- for iprim in range(nprim):
47
- row = [float(coefficients[ic][iprim]) for ic in range(ncontr)]
48
- row.insert(0, float(exponents[iprim]))
49
- shell_data.append(row)
50
- atom_shells.append(shell_data)
46
+ if len(am) == len(coefficients): # SP basis
47
+ for l, c in zip(am, coefficients):
48
+ shell_data = [l]
49
+ for iprim in range(nprim):
50
+ row = [float(exponents[iprim]), float(c[iprim])]
51
+ shell_data.append(row)
52
+ atom_shells.append(shell_data)
53
+ else:
54
+ assert len(am) == 1
55
+ shell_data = [am[0]]
56
+ for iprim in range(nprim):
57
+ row = [float(coefficients[ic][iprim]) for ic in range(ncontr)]
58
+ row.insert(0, float(exponents[iprim]))
59
+ shell_data.append(row)
60
+ atom_shells.append(shell_data)
51
61
  r[sym] = atom_shells
52
62
 
53
63
  # Collect the literature references
54
- for ref in data['references']:
55
- for key in ref['reference_keys']:
56
- if key not in reference_list:
57
- reference_list.append(key)
64
+ if 'references' in data:
65
+ for ref in data['references']:
66
+ for key in ref['reference_keys']:
67
+ if key not in reference_list:
68
+ reference_list.append(key)
58
69
 
59
70
  return r, reference_list
60
71
 
@@ -110,6 +121,48 @@ def _print_basis_information(basis):
110
121
  print('Last revised on {}'.format(revision_date))
111
122
  print('Revision description: {}'.format(revision_description))
112
123
 
124
+ def get_basis(name, elements):
125
+ '''
126
+ Obtain a basis set
127
+
128
+ Args:
129
+ name : str
130
+ Name of the basis set, case insensitive.
131
+ elements : str, int or list
132
+
133
+ Returns:
134
+ A dict of basis set in PySCF internal basis format.
135
+ '''
136
+ basis = basis_set_exchange.api.get_basis(name, elements)
137
+ return _orbital_basis(basis)[0]
138
+
139
+ def autoaux(name, elements):
140
+ '''
141
+ Create an auxiliary basis set for the given orbital basis set using
142
+ the Auto-Aux algorithm.
143
+
144
+ See also: G. L. Stoychev, A. A. Auer, and F. Neese
145
+ Automatic Generation of Auxiliary Basis Sets
146
+ J. Chem. Theory Comput. 13, 554 (2017)
147
+ http://doi.org/10.1021/acs.jctc.6b01041
148
+ '''
149
+ obs = basis_set_exchange.api.get_basis(name, elements)
150
+ auxbs = manip.autoaux_basis(obs)
151
+ return _orbital_basis(auxbs)[0]
152
+
153
+ def autoabs(name, elements):
154
+ '''
155
+ Create a Coulomb fitting basis set for the given orbital basis set.
156
+ See also:
157
+ R. Yang, A. P. Rendell, and M. J. Frisch
158
+ Automatically generated Coulomb fitting basis sets: Design and accuracy for systems containing H to Kr
159
+ J. Chem. Phys. 127, 074102 (2007)
160
+ http://doi.org/10.1063/1.2752807
161
+ '''
162
+ obs = basis_set_exchange.api.get_basis(name, elements)
163
+ auxbs = manip.autoabs_basis(obs)
164
+ return _orbital_basis(auxbs)[0]
165
+
113
166
  if __name__ == '__main__':
114
167
  from basis_set_exchange import api, references
115
168
 
@@ -84,7 +84,7 @@ def _parse(plines):
84
84
  for h in plines.pop(0).split():
85
85
  hproj_p_ij.append(float(h))
86
86
  hproj_p = np.zeros((nproj[-1],nproj[-1]))
87
- hproj_p[np.triu_indices(nproj[-1])] = [ h for h in hproj_p_ij ]
87
+ hproj_p[np.triu_indices(nproj[-1])] = list(hproj_p_ij)
88
88
  hproj_p_symm = hproj_p + hproj_p.T - np.diag(hproj_p.diagonal())
89
89
  hproj.append(hproj_p_symm.tolist())
90
90
 
@@ -212,7 +212,7 @@ def optimize_contraction(basis):
212
212
  key = tuple(b[:1])
213
213
  ec = numpy.array(b[1:]).T
214
214
  es = ec[0]
215
- cs = [c for c in ec[1:]]
215
+ cs = list(ec[1:])
216
216
 
217
217
  if key not in basdic:
218
218
  basdic[key] = []
@@ -109,7 +109,8 @@ def _parse_ecp(raw_ecp):
109
109
  coef = list(eval(','.join(line[1:])))
110
110
  except Exception:
111
111
  raise BasisNotFoundError('Not basis data')
112
- by_ang[l].append(coef)
112
+ if any(x != 0 for x in coef[1:]):
113
+ by_ang[l].append(coef)
113
114
 
114
115
  if nelec is None:
115
116
  return []