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/scf/addons.py CHANGED
@@ -44,6 +44,18 @@ def smearing(mf, sigma=None, method=SMEARING_METHOD, mu0=None, fix_spin=False):
44
44
  return mf
45
45
 
46
46
  assert not mf.istype('KSCF')
47
+ if mf.istype('ROHF'):
48
+ # Roothaan Fock matrix does not make much sense for smearing.
49
+ # Restore the conventional RHF treatment.
50
+ from pyscf import scf
51
+ from pyscf import dft
52
+ known_class = {
53
+ dft.rks_symm.ROKS: dft.rks_symm.RKS,
54
+ dft.roks.ROKS : dft.rks.RKS ,
55
+ scf.hf_symm.ROHF : scf.hf_symm.RHF ,
56
+ scf.rohf.ROHF : scf.hf.RHF ,
57
+ }
58
+ mf = _object_without_soscf(mf, known_class)
47
59
  return lib.set_class(_SmearingSCF(mf, sigma, method, mu0, fix_spin),
48
60
  (_SmearingSCF, mf.__class__))
49
61
 
@@ -69,13 +81,13 @@ def _gaussian_smearing_occ(mu, mo_energy, sigma):
69
81
  return 0.5 * scipy.special.erfc((mo_energy - mu) / sigma)
70
82
 
71
83
  def _smearing_optimize(f_occ, mo_es, nocc, sigma):
72
- def nelec_cost_fn(m, mo_es, nocc):
84
+ def nelec_cost_fn(m):
73
85
  mo_occ = f_occ(m, mo_es, sigma)
74
86
  return (mo_occ.sum() - nocc)**2
75
87
 
76
88
  fermi = _get_fermi(mo_es, nocc)
77
89
  res = scipy.optimize.minimize(
78
- nelec_cost_fn, fermi, args=(mo_es, nocc), method='Powell',
90
+ nelec_cost_fn, fermi, method='Powell',
79
91
  options={'xtol': 1e-5, 'ftol': 1e-5, 'maxiter': 10000})
80
92
  mu = res.x
81
93
  mo_occs = f_occ(mu, mo_es, sigma)
@@ -83,7 +95,10 @@ def _smearing_optimize(f_occ, mo_es, nocc, sigma):
83
95
 
84
96
  def _get_fermi(mo_energy, nocc):
85
97
  mo_e_sorted = numpy.sort(mo_energy)
86
- return mo_e_sorted[nocc-1]
98
+ if isinstance(nocc, int):
99
+ return mo_e_sorted[nocc-1]
100
+ else: # nocc = ?.5 or nocc = ?.0
101
+ return mo_e_sorted[numpy.ceil(nocc).astype(int) - 1]
87
102
 
88
103
  class _SmearingSCF:
89
104
 
@@ -116,6 +131,7 @@ class _SmearingSCF:
116
131
  def get_occ(self, mo_energy=None, mo_coeff=None):
117
132
  '''Label the occupancies for each orbital
118
133
  '''
134
+ from pyscf import scf
119
135
  from pyscf.pbc.tools import print_mo_energy_occ
120
136
  if (self.sigma == 0) or (not self.sigma) or (not self.smearing_method):
121
137
  mo_occ = super().get_occ(mo_energy, mo_coeff)
@@ -123,7 +139,10 @@ class _SmearingSCF:
123
139
 
124
140
  is_uhf = self.istype('UHF')
125
141
  is_rhf = self.istype('RHF')
126
- is_rohf = self.istype('ROHF')
142
+ if isinstance(self, scf.rohf.ROHF):
143
+ # ROHF leads to two Fock matrices. It's not clear how to define the
144
+ # Roothaan effective Fock matrix from the two.
145
+ raise NotImplementedError('Smearing-ROHF')
127
146
 
128
147
  sigma = self.sigma
129
148
  if self.smearing_method.lower() == 'fermi':
@@ -131,11 +150,8 @@ class _SmearingSCF:
131
150
  else:
132
151
  f_occ = _gaussian_smearing_occ
133
152
 
134
- if self.fix_spin and (is_uhf or is_rohf): # spin separated fermi level
135
- if is_rohf: # treat rohf as uhf
136
- mo_es = (mo_energy, mo_energy)
137
- else:
138
- mo_es = mo_energy
153
+ if self.fix_spin and is_uhf: # spin separated fermi level
154
+ mo_es = mo_energy
139
155
  nocc = self.nelec
140
156
  if self.mu0 is None:
141
157
  mu_a, occa = _smearing_optimize(f_occ, mo_es[0], nocc[0], sigma)
@@ -165,19 +181,17 @@ class _SmearingSCF:
165
181
  sigma, mu[1], self.entropy)
166
182
  if self.verbose >= logger.DEBUG:
167
183
  print_mo_energy_occ(self, mo_energy, mo_occs, True)
168
- if is_rohf:
169
- mo_occs = mo_occs[0] + mo_occs[1]
170
184
  else: # all orbitals treated with the same fermi level
171
- nocc = nelectron = self.mol.nelectron
185
+ nelectron = self.mol.nelectron
172
186
  if is_uhf:
173
187
  mo_es = numpy.hstack(mo_energy)
174
188
  else:
175
189
  mo_es = mo_energy
176
190
  if is_rhf:
177
- nocc = (nelectron + 1) // 2
191
+ nelectron = nelectron / 2
178
192
 
179
193
  if self.mu0 is None:
180
- mu, mo_occs = _smearing_optimize(f_occ, mo_es, nocc, sigma)
194
+ mu, mo_occs = _smearing_optimize(f_occ, mo_es, nelectron, sigma)
181
195
  else:
182
196
  # If mu0 is given, fix mu instead of electron number. XXX -Chong Sun
183
197
  mu = self.mu0
@@ -188,7 +202,7 @@ class _SmearingSCF:
188
202
  mo_occs *= 2
189
203
  self.entropy *= 2
190
204
 
191
- fermi = _get_fermi(mo_es, nocc)
205
+ fermi = _get_fermi(mo_es, nelectron)
192
206
  logger.debug(self, ' Fermi level %g Sum mo_occ = %s should equal nelec = %s',
193
207
  fermi, mo_occs.sum(), nelectron)
194
208
  logger.info(self, ' sigma = %g Optimized mu = %.12g entropy = %.12g',
pyscf/scf/cphf.py CHANGED
@@ -17,7 +17,7 @@
17
17
  #
18
18
 
19
19
  '''
20
- Restricted coupled pertubed Hartree-Fock solver
20
+ Restricted coupled perturbed Hartree-Fock solver
21
21
  '''
22
22
 
23
23
 
@@ -68,15 +68,16 @@ def solve_nos1(fvind, mo_energy, mo_occ, h1,
68
68
  e_i = mo_energy[mo_occ>0]
69
69
  e_ai = 1 / (e_a[:,None] + level_shift - e_i)
70
70
  mo1base = h1 * -e_ai
71
+ nvir, nocc = e_ai.shape
71
72
 
72
73
  def vind_vo(mo1):
73
- mo1 = mo1.reshape(h1.shape)
74
- v = fvind(mo1).reshape(h1.shape)
74
+ mo1 = mo1.reshape(-1, nvir, nocc)
75
+ v = fvind(mo1).reshape(-1, nvir, nocc)
75
76
  if level_shift != 0:
76
77
  v -= mo1 * level_shift
77
78
  v *= e_ai
78
- return v.ravel()
79
- mo1 = lib.krylov(vind_vo, mo1base.ravel(),
79
+ return v.reshape(-1, nvir*nocc)
80
+ mo1 = lib.krylov(vind_vo, mo1base.reshape(-1, nvir*nocc),
80
81
  tol=tol, max_cycle=max_cycle, hermi=hermi, verbose=log)
81
82
  log.timer('krylov solver in CPHF', *t0)
82
83
  return mo1.reshape(h1.shape), None
@@ -119,20 +120,20 @@ def solve_withs1(fvind, mo_energy, mo_occ, h1, s1,
119
120
  mo1base[:,occidx] = -s1[:,occidx] * .5
120
121
 
121
122
  def vind_vo(mo1):
122
- mo1 = mo1.reshape(mo1base.shape)
123
- v = fvind(mo1).reshape(mo1base.shape)
123
+ mo1 = mo1.reshape(-1, nmo, nocc)
124
+ v = fvind(mo1).reshape(-1, nmo, nocc)
124
125
  if level_shift != 0:
125
126
  v -= mo1 * level_shift
126
127
  v[:,viridx,:] *= e_ai
127
128
  v[:,occidx,:] = 0
128
- return v.ravel()
129
- mo1 = lib.krylov(vind_vo, mo1base.ravel(),
129
+ return v.reshape(-1, nmo*nocc)
130
+ mo1 = lib.krylov(vind_vo, mo1base.reshape(-1, nmo*nocc),
130
131
  tol=tol, max_cycle=max_cycle, hermi=hermi, verbose=log)
131
- mo1 = mo1.reshape(mo1base.shape)
132
+ mo1 = mo1.reshape(-1, nmo, nocc)
132
133
  mo1[:,occidx] = mo1base[:,occidx]
133
134
  log.timer('krylov solver in CPHF', *t0)
134
135
 
135
- hs += fvind(mo1).reshape(mo1base.shape)
136
+ hs += fvind(mo1).reshape(-1, nmo, nocc)
136
137
  mo1[:,viridx] = hs[:,viridx] / (e_i - e_a[:,None])
137
138
 
138
139
  # mo_e1 has the same symmetry as the first order Fock matrix (hermitian or
@@ -143,44 +144,5 @@ def solve_withs1(fvind, mo_energy, mo_occ, h1, s1,
143
144
  if h1.ndim == 3:
144
145
  return mo1, mo_e1
145
146
  else:
146
- return mo1.reshape(h1.shape), mo_e1.reshape(nocc,nocc)
147
-
148
- if __name__ == '__main__':
149
- numpy.random.seed(1)
150
- nd = 3
151
- nocc = 5
152
- nmo = 12
153
- nvir = nmo - nocc
154
- a = numpy.random.random((nocc*nvir,nocc*nvir))
155
- a = a + a.T
156
- def fvind(x):
157
- v = numpy.dot(a,x[:,nocc:].reshape(-1,nocc*nvir).T)
158
- v1 = numpy.zeros((nd,nmo,nocc))
159
- v1[:,nocc:] = v.T.reshape(nd,nvir,nocc)
160
- return v1
161
- mo_energy = numpy.sort(numpy.random.random(nmo)) * 10
162
- mo_occ = numpy.zeros(nmo)
163
- mo_occ[:nocc] = 2
164
- e_i = mo_energy[mo_occ>0]
165
- e_a = mo_energy[mo_occ==0]
166
- e_ai = 1 / lib.direct_sum('a-i->ai', e_a, e_i)
167
- h1 = numpy.random.random((nd,nmo,nocc))
168
- h1[:,:nocc,:nocc] = h1[:,:nocc,:nocc] + h1[:,:nocc,:nocc].transpose(0,2,1)
169
- s1 = numpy.random.random((nd,nmo,nocc))
170
- s1[:,:nocc,:nocc] = s1[:,:nocc,:nocc] + s1[:,:nocc,:nocc].transpose(0,2,1)
171
-
172
- x = solve(fvind, mo_energy, mo_occ, h1, s1, max_cycle=30)[0]
173
- print(numpy.linalg.norm(x)-6.272581531366389)
174
- hs = h1.reshape(-1,nmo,nocc) - s1.reshape(-1,nmo,nocc)*e_i
175
- print(abs(hs[:,nocc:] + fvind(x)[:,nocc:]+x[:,nocc:]/e_ai).sum())
176
-
177
- ################
178
- xref = solve(fvind, mo_energy, mo_occ, h1, s1*0, max_cycle=30)[0][:,mo_occ==0]
179
- def fvind(x):
180
- return numpy.dot(a,x.reshape(nd,nocc*nvir).T).T.reshape(nd,nvir,nocc)
181
- h1 = h1[:,nocc:]
182
- x0 = numpy.linalg.solve(numpy.diag(1/e_ai.ravel())+a, -h1.reshape(nd,-1).T).T.reshape(nd,nvir,nocc)
183
- x1 = solve(fvind, mo_energy, mo_occ, h1, max_cycle=30)[0]
184
- print(abs(x0-x1).sum())
185
- print(abs(xref-x1).sum())
186
- print(abs(h1 + fvind(x1)+x1/e_ai).sum())
147
+ assert h1.ndim == 2
148
+ return mo1[0], mo_e1[0]
pyscf/scf/dhf.py CHANGED
@@ -62,11 +62,13 @@ def kernel(mf, conv_tol=1e-9, conv_tol_grad=None,
62
62
  dm = dm0
63
63
 
64
64
  mf._coulomb_level = 'LLLL'
65
+ cycles = 0
65
66
  if dm0 is None and mf._coulomb_level.upper() == 'LLLL':
66
67
  scf_conv, e_tot, mo_energy, mo_coeff, mo_occ \
67
68
  = hf.kernel(mf, 1e-2, 1e-1,
68
69
  dump_chk, dm0=dm, callback=callback,
69
70
  conv_check=False)
71
+ cycles += mf.cycles
70
72
  dm = mf.make_rdm1(mo_coeff, mo_occ)
71
73
  mf._coulomb_level = 'SSLL'
72
74
 
@@ -77,13 +79,16 @@ def kernel(mf, conv_tol=1e-9, conv_tol_grad=None,
77
79
  = hf.kernel(mf, 1e-3, 1e-1,
78
80
  dump_chk, dm0=dm, callback=callback,
79
81
  conv_check=False)
82
+ cycles += mf.cycles
80
83
  dm = mf.make_rdm1(mo_coeff, mo_occ)
81
84
  mf._coulomb_level = 'SSSS'
82
85
  else:
83
86
  mf._coulomb_level = 'SSLL'
84
87
 
85
- return hf.kernel(mf, conv_tol, conv_tol_grad, dump_chk, dm0=dm,
86
- callback=callback, conv_check=conv_check)
88
+ out = hf.kernel(mf, conv_tol, conv_tol_grad, dump_chk, dm0=dm,
89
+ callback=callback, conv_check=conv_check)
90
+ mf.cycles = cycles + mf.cycles
91
+ return out
87
92
 
88
93
  def energy_elec(mf, dm=None, h1e=None, vhf=None):
89
94
  r'''Electronic part of Dirac-Hartree-Fock energy
@@ -93,7 +98,7 @@ def energy_elec(mf, dm=None, h1e=None, vhf=None):
93
98
 
94
99
  Kwargs:
95
100
  dm : 2D ndarray
96
- one-partical density matrix
101
+ one-particle density matrix
97
102
  h1e : 2D ndarray
98
103
  Core hamiltonian
99
104
  vhf : 2D ndarray
@@ -232,6 +237,24 @@ def init_guess_by_mod_huckel(mol):
232
237
  dm = hf.init_guess_by_mod_huckel(mol)
233
238
  return _proj_dmll(mol, dm, mol)
234
239
 
240
+ def init_guess_by_sap(mol, mf):
241
+ '''Generate initial guess density matrix from a superposition of
242
+ atomic potentials (SAP), doi:10.1021/acs.jctc.8b01089.
243
+ This is the Gaussian fit implementation, see doi:10.1063/5.0004046.
244
+
245
+ Args:
246
+ mol : MoleBase object
247
+ the molecule object for which the initial guess is evaluated
248
+ sap_basis : dict
249
+ SAP basis in internal format (python dictionary)
250
+
251
+ Returns:
252
+ dm0 : ndarray
253
+ SAP initial guess density matrix
254
+ '''
255
+ dm = hf.SCF.init_guess_by_sap(mf, mol)
256
+ return _proj_dmll(mol, dm, mol)
257
+
235
258
  def init_guess_by_chkfile(mol, chkfile_name, project=None):
236
259
  '''Read SCF chkfile and make the density matrix for 4C-DHF initial guess.
237
260
 
@@ -290,7 +313,7 @@ def get_init_guess(mol, key='minao', **kwargs):
290
313
 
291
314
  Kwargs:
292
315
  key : str
293
- One of 'minao', 'atom', 'huckel', 'mod_huckel', 'hcore', '1e', 'chkfile'.
316
+ One of 'minao', 'atom', 'huckel', 'mod_huckel', 'hcore', '1e', 'sap', 'chkfile'.
294
317
  '''
295
318
  return UHF(mol).get_init_guess(mol, key, **kwargs)
296
319
 
@@ -398,7 +421,7 @@ def dip_moment(mol, dm, unit='Debye', verbose=logger.NOTE, **kwargs):
398
421
 
399
422
  charges = mol.atom_charges()
400
423
  coords = mol.atom_coords()
401
- charge_center = numpy.einsum('i,ix->x', charges, coords)
424
+ charge_center = numpy.einsum('i,ix->x', charges, coords) / sum(charges)
402
425
  with mol.with_common_orig(charge_center):
403
426
  ll_dip = mol.intor_symmetric('int1e_r_spinor', comp=3)
404
427
  ss_dip = mol.intor_symmetric('int1e_sprsp_spinor', comp=3)
@@ -406,7 +429,9 @@ def dip_moment(mol, dm, unit='Debye', verbose=logger.NOTE, **kwargs):
406
429
  n2c = mol.nao_2c()
407
430
  c = lib.param.LIGHT_SPEED
408
431
  dip = numpy.einsum('xij,ji->x', ll_dip, dm[:n2c,:n2c]).real
409
- dip+= numpy.einsum('xij,ji->x', ss_dip, dm[n2c:,n2c:]).real * (.5/c**2)
432
+ dip+= numpy.einsum('xij,ji->x', ss_dip, dm[n2c:,n2c:]).real * (.5/c)**2
433
+
434
+ dip *= -1.
410
435
 
411
436
  if unit.upper() == 'DEBYE':
412
437
  dip *= nist.AU2DEBYE
@@ -453,8 +478,7 @@ class DHF(hf.SCF):
453
478
  # corrections for small component when with_ssss is set to False
454
479
  ssss_approx = getattr(__config__, 'scf_dhf_SCF_ssss_approx', 'Visscher')
455
480
 
456
- _keys = {'conv_tol', 'with_ssss', 'with_gaunt',
457
- 'with_breit', 'ssss_approx'}
481
+ _keys = {'conv_tol', 'with_ssss', 'with_gaunt', 'with_breit', 'ssss_approx'}
458
482
 
459
483
  def __init__(self, mol):
460
484
  hf.SCF.__init__(self, mol)
@@ -510,6 +534,11 @@ class DHF(hf.SCF):
510
534
  employing the updated GWH rule from doi:10.1021/ja00480a005.''')
511
535
  return init_guess_by_mod_huckel(mol)
512
536
 
537
+ @lib.with_doc(hf.SCF.init_guess_by_sap.__doc__)
538
+ def init_guess_by_sap(self, mol=None, **kwargs):
539
+ if mol is None: mol = self.mol
540
+ return init_guess_by_sap(mol, self)
541
+
513
542
  def init_guess_by_chkfile(self, chkfile=None, project=None):
514
543
  if chkfile is None: chkfile = self.chkfile
515
544
  return init_guess_by_chkfile(self.mol, chkfile, project=project)
@@ -685,7 +714,7 @@ employing the updated GWH rule from doi:10.1021/ja00480a005.''')
685
714
  self._opt = {None: None}
686
715
  return self
687
716
 
688
- def stability(self, internal=None, external=None, verbose=None, return_status=False):
717
+ def stability(self, internal=None, external=None, verbose=None, return_status=False, **kwargs):
689
718
  '''
690
719
  DHF/DKS stability analysis.
691
720
 
@@ -707,7 +736,7 @@ employing the updated GWH rule from doi:10.1021/ja00480a005.''')
707
736
  and the second corresponds to the external stability.
708
737
  '''
709
738
  from pyscf.scf.stability import dhf_stability
710
- return dhf_stability(self, verbose, return_status)
739
+ return dhf_stability(self, verbose, return_status, **kwargs)
711
740
 
712
741
  def to_rhf(self):
713
742
  raise RuntimeError
pyscf/scf/dispersion.py CHANGED
@@ -23,6 +23,7 @@ dispersion correction for HF and DFT
23
23
  import warnings
24
24
  from functools import lru_cache
25
25
  from pyscf.lib import logger
26
+ from pyscf import scf
26
27
 
27
28
  # supported dispersion corrections
28
29
  DISP_VERSIONS = ['d3bj', 'd3zero', 'd3bjm', 'd3zerom', 'd3op', 'd4']
@@ -115,8 +116,13 @@ def check_disp(mf, disp=None):
115
116
  if disp == 0: # disp = False
116
117
  return False
117
118
 
118
- # The disp method for both HF and MCSCF is set to 'hf'
119
- method = getattr(mf, 'xc', 'hf')
119
+ # To prevent mf.do_disp() triggering the SCF.__getattr__ method, do not use
120
+ # method = getattr(mf, 'xc', 'hf').
121
+ if isinstance(mf, scf.hf.KohnShamDFT):
122
+ method = mf.xc
123
+ else:
124
+ # Set the disp method for both HF and MCSCF to 'hf'
125
+ method = 'hf'
120
126
  disp_version = parse_disp(method)[1]
121
127
 
122
128
  if disp is None: # Using the disp version decoded from the mf.xc attribute
@@ -169,9 +175,4 @@ def get_dispersion(mf, disp=None, with_3body=None, verbose=None):
169
175
  mf.scf_summary['dispersion'] = e_d4
170
176
  return e_d4
171
177
  else:
172
- raise RuntimeError(f'dipersion correction: {disp_version} is not supported.')
173
-
174
- # Inject to SCF class
175
- from pyscf import scf
176
- scf.hf.SCF.do_disp = check_disp
177
- scf.hf.SCF.get_dispersion = get_dispersion
178
+ raise RuntimeError(f'dispersion correction: {disp_version} is not supported.')
pyscf/scf/ghf.py CHANGED
@@ -287,7 +287,7 @@ def spin_square(mo, s=1):
287
287
  return ss, s*2+1
288
288
 
289
289
  def analyze(mf, verbose=logger.DEBUG, with_meta_lowdin=WITH_META_LOWDIN,
290
- **kwargs):
290
+ origin=None, **kwargs):
291
291
  '''Analyze the given SCF object: print orbital energies, occupancies;
292
292
  print orbital coefficients; Mulliken population analysis; Dipole moment
293
293
  '''
@@ -301,7 +301,7 @@ def analyze(mf, verbose=logger.DEBUG, with_meta_lowdin=WITH_META_LOWDIN,
301
301
  log.note('MO #%-3d energy= %-18.15g occ= %g', i+MO_BASE, mo_energy[i], c)
302
302
  ovlp_ao = mf.get_ovlp()
303
303
  dm = mf.make_rdm1(mo_coeff, mo_occ)
304
- dip = mf.dip_moment(mf.mol, dm, verbose=log)
304
+ dip = mf.dip_moment(mf.mol, dm, origin=origin, verbose=log)
305
305
  if with_meta_lowdin:
306
306
  pop_and_chg = mf.mulliken_meta(mf.mol, dm, s=ovlp_ao, verbose=log)
307
307
  else:
@@ -316,7 +316,7 @@ def mulliken_pop(mol, dm, s=None, verbose=logger.DEBUG):
316
316
  dmb = dm[nao:,nao:]
317
317
  if s is not None:
318
318
  assert (s.size == nao**2 or numpy.allclose(s[:nao,:nao], s[nao:,nao:]))
319
- s = s[:nao,:nao]
319
+ s = lib.asarray(s[:nao,:nao], order='C')
320
320
  return uhf.mulliken_pop(mol, (dma,dmb), s, verbose)
321
321
 
322
322
  def mulliken_meta(mol, dm_ao, verbose=logger.DEBUG,
@@ -328,7 +328,7 @@ def mulliken_meta(mol, dm_ao, verbose=logger.DEBUG,
328
328
  dmb = dm_ao[nao:,nao:]
329
329
  if s is not None:
330
330
  assert (s.size == nao**2 or numpy.allclose(s[:nao,:nao], s[nao:,nao:]))
331
- s = s[:nao,:nao]
331
+ s = lib.asarray(s[:nao,:nao], order='C')
332
332
  return uhf.mulliken_meta(mol, (dma,dmb), verbose, pre_orth_method, s)
333
333
 
334
334
  def det_ovlp(mo1, mo2, occ1, occ2, ovlp):
@@ -349,11 +349,11 @@ def det_ovlp(mo1, mo2, occ1, occ2, ovlp):
349
349
  x = numpy.dot(u/s, vt)
350
350
  return numpy.prod(s), x
351
351
 
352
- def dip_moment(mol, dm, unit_symbol='Debye', verbose=logger.NOTE):
352
+ def dip_moment(mol, dm, unit_symbol='Debye', origin=None, verbose=logger.NOTE):
353
353
  nao = mol.nao_nr()
354
354
  dma = dm[:nao,:nao]
355
355
  dmb = dm[nao:,nao:]
356
- return hf.dip_moment(mol, dma+dmb, unit_symbol, verbose)
356
+ return hf.dip_moment(mol, dma+dmb, unit=unit_symbol, verbose=verbose, origin=origin)
357
357
 
358
358
  canonicalize = hf.canonicalize
359
359
 
@@ -438,6 +438,12 @@ class GHF(hf.SCF):
438
438
  employing the updated GWH rule from doi:10.1021/ja00480a005.''')
439
439
  return _from_rhf_init_dm(hf.init_guess_by_mod_huckel(mol))
440
440
 
441
+ @lib.with_doc(hf.SCF.init_guess_by_sap.__doc__)
442
+ def init_guess_by_sap(self, mol=None, **kwargs):
443
+ return _from_rhf_init_dm(
444
+ hf.SCF.init_guess_by_sap(self, mol, **kwargs)
445
+ )
446
+
441
447
  @lib.with_doc(hf.SCF.init_guess_by_chkfile.__doc__)
442
448
  def init_guess_by_chkfile(self, chkfile=None, project=None):
443
449
  if chkfile is None: chkfile = self.chkfile
@@ -504,10 +510,10 @@ employing the updated GWH rule from doi:10.1021/ja00480a005.''')
504
510
 
505
511
  @lib.with_doc(dip_moment.__doc__)
506
512
  def dip_moment(self, mol=None, dm=None, unit_symbol='Debye',
507
- verbose=logger.NOTE):
513
+ origin=None, verbose=logger.NOTE):
508
514
  if mol is None: mol = self.mol
509
515
  if dm is None: dm = self.make_rdm1()
510
- return dip_moment(mol, dm, unit_symbol, verbose=verbose)
516
+ return dip_moment(mol, dm, unit_symbol, origin=origin, verbose=verbose)
511
517
 
512
518
  def convert_from_(self, mf):
513
519
  '''Create GHF object based on the RHF/UHF object'''
@@ -515,9 +521,9 @@ employing the updated GWH rule from doi:10.1021/ja00480a005.''')
515
521
  self.__dict__.update(tgt.__dict__)
516
522
  return self
517
523
 
518
- def stability(self, internal=None, external=None, verbose=None, return_status=False):
524
+ def stability(self, internal=None, external=None, verbose=None, return_status=False, **kwargs):
519
525
  from pyscf.scf.stability import ghf_stability
520
- return ghf_stability(self, verbose, return_status)
526
+ return ghf_stability(self, verbose, return_status, **kwargs)
521
527
 
522
528
  def nuc_grad_method(self):
523
529
  raise NotImplementedError
@@ -525,9 +531,15 @@ employing the updated GWH rule from doi:10.1021/ja00480a005.''')
525
531
  def x2c1e(self):
526
532
  '''X2C with spin-orbit coupling effects.
527
533
 
528
- Note the difference to PySCF-1.7. In PySCF it calls spin-free X2C1E.
529
- This result (mol.GHF().x2c() ) should equal to mol.X2C() although they
530
- are solved in different AO basis (spherical GTO vs spinor GTO)
534
+ Starting from PySCF 2.1, this function (mol.GHF().x2c()) produces an X2C
535
+ calculation in spherical GTO bases. The results in theory are equivalent
536
+ to those obtained from the mol.X2C() method, which is computed in the
537
+ spinor GTO bases. This function called the spin-free X2C1E method in the
538
+ older versions.
539
+
540
+ Please note the difference from other SCF methods, such as RHF and UHF.
541
+ In those methods, the .x2c() method produces a scalar relativistic
542
+ calculation using the X2C Hamiltonian.
531
543
  '''
532
544
  from pyscf.x2c.x2c import x2c1e_ghf
533
545
  return x2c1e_ghf(self)
pyscf/scf/ghf_symm.py CHANGED
@@ -153,8 +153,8 @@ class SymAdaptedGHF(ghf.GHF):
153
153
 
154
154
  nirrep = len(symm_orb)
155
155
  symm_orb = [scipy.linalg.block_diag(c, c) for c in symm_orb]
156
- s = [reduce(numpy.dot, (c.T,s,c)) for c in symm_orb]
157
- h = [reduce(numpy.dot, (c.T,h,c)) for c in symm_orb]
156
+ h = symm.symmetrize_matrix(h, symm_orb)
157
+ s = symm.symmetrize_matrix(s, symm_orb)
158
158
  cs = []
159
159
  es = []
160
160
  orbsym = []