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.
- pyscf/__init__.py +2 -2
- pyscf/adc/__init__.py +3 -8
- pyscf/adc/dfadc.py +22 -6
- pyscf/adc/radc.py +106 -15
- pyscf/adc/radc_amplitudes.py +7 -1
- pyscf/adc/radc_ao2mo.py +4 -2
- pyscf/adc/radc_ea.py +524 -8
- pyscf/adc/radc_ip.py +492 -60
- pyscf/adc/radc_ip_cvs.py +4 -2
- pyscf/adc/uadc.py +116 -27
- pyscf/adc/uadc_amplitudes.py +215 -20
- pyscf/adc/uadc_ao2mo.py +30 -9
- pyscf/adc/uadc_ea.py +34 -44
- pyscf/adc/uadc_ip.py +9 -4
- pyscf/adc/uadc_ip_cvs.py +4 -1
- pyscf/agf2/__init__.py +2 -2
- pyscf/agf2/aux_space.py +1 -1
- pyscf/agf2/chkfile.py +1 -1
- pyscf/ao2mo/__init__.py +13 -2
- pyscf/ao2mo/_ao2mo.py +10 -1
- pyscf/ao2mo/incore.py +3 -0
- pyscf/ao2mo/nrr_outcore.py +2 -2
- pyscf/ao2mo/outcore.py +9 -7
- pyscf/ao2mo/r_outcore.py +2 -2
- pyscf/cc/__init__.py +21 -3
- pyscf/cc/bccd.py +0 -46
- pyscf/cc/ccsd.py +29 -13
- pyscf/cc/ccsd_rdm.py +6 -1
- pyscf/cc/gccsd.py +2 -2
- pyscf/cc/uccsd.py +7 -7
- pyscf/cc/uccsd_rdm.py +2 -2
- pyscf/data/elements.py +1 -1
- pyscf/df/__init__.py +2 -1
- pyscf/df/addons.py +79 -51
- pyscf/df/autoaux.py +195 -0
- pyscf/df/df.py +5 -1
- pyscf/df/df_jk.py +27 -25
- pyscf/df/grad/casscf.py +0 -41
- pyscf/df/grad/rhf.py +31 -1
- pyscf/df/hessian/rhf.py +2 -10
- pyscf/df/hessian/rks.py +1 -7
- pyscf/df/hessian/uhf.py +3 -13
- pyscf/df/hessian/uks.py +1 -8
- pyscf/df/incore.py +18 -6
- pyscf/df/outcore.py +6 -6
- pyscf/dft/dks.py +1 -1
- pyscf/dft/gks.py +25 -21
- pyscf/dft/libxc.py +91 -645
- pyscf/dft/numint.py +40 -19
- pyscf/dft/radi.py +48 -7
- pyscf/dft/rks.py +29 -25
- pyscf/dft/roks.py +7 -1
- pyscf/dft/uks.py +34 -25
- pyscf/dft/xc_deriv.py +1 -1
- pyscf/dft/xcfun.py +53 -2
- pyscf/eph/eph_fd.py +1 -1
- pyscf/eph/rhf.py +6 -36
- pyscf/eph/rks.py +0 -4
- pyscf/eph/uhf.py +1 -7
- pyscf/eph/uks.py +1 -7
- pyscf/fci/addons.py +117 -2
- pyscf/fci/cistring.py +1 -1
- pyscf/fci/direct_nosym.py +3 -3
- pyscf/fci/direct_spin0_symm.py +22 -43
- pyscf/fci/direct_spin1.py +65 -10
- pyscf/fci/direct_spin1_symm.py +49 -14
- pyscf/fci/direct_uhf.py +4 -4
- pyscf/fci/selected_ci_symm.py +1 -1
- pyscf/grad/ccsd.py +3 -7
- pyscf/grad/ccsd_slow.py +2 -3
- pyscf/grad/lagrange.py +11 -3
- pyscf/grad/mp2.py +13 -4
- pyscf/grad/sacasscf.py +1 -1
- pyscf/grad/tdrks.py +1 -1
- pyscf/grad/uccsd.py +3 -7
- pyscf/grad/ump2.py +2 -4
- pyscf/gto/basis/__init__.py +17 -4
- pyscf/gto/basis/bse.py +68 -15
- pyscf/gto/basis/def2-mtzvp.dat +4719 -0
- pyscf/gto/basis/def2-mtzvpp.dat +4739 -0
- pyscf/gto/basis/dyall-basis/__init__.py +0 -0
- pyscf/gto/basis/dyall-basis/dyall_2zp.py +6492 -0
- pyscf/gto/basis/dyall-basis/dyall_3zp.py +8343 -0
- pyscf/gto/basis/dyall-basis/dyall_4zp.py +10055 -0
- pyscf/gto/basis/dyall-basis/dyall_aae2z.py +1818 -0
- pyscf/gto/basis/dyall-basis/dyall_aae3z.py +2521 -0
- pyscf/gto/basis/dyall-basis/dyall_aae4z.py +3351 -0
- pyscf/gto/basis/dyall-basis/dyall_acv2z.py +1790 -0
- pyscf/gto/basis/dyall-basis/dyall_acv3z.py +2417 -0
- pyscf/gto/basis/dyall-basis/dyall_acv4z.py +3085 -0
- pyscf/gto/basis/dyall-basis/dyall_ae2z.py +6619 -0
- pyscf/gto/basis/dyall-basis/dyall_ae3z.py +9027 -0
- pyscf/gto/basis/dyall-basis/dyall_ae4z.py +11839 -0
- pyscf/gto/basis/dyall-basis/dyall_av2z.py +1742 -0
- pyscf/gto/basis/dyall-basis/dyall_av3z.py +2318 -0
- pyscf/gto/basis/dyall-basis/dyall_av4z.py +2905 -0
- pyscf/gto/basis/dyall-basis/dyall_cv2z.py +6558 -0
- pyscf/gto/basis/dyall-basis/dyall_cv3z.py +8767 -0
- pyscf/gto/basis/dyall-basis/dyall_cv4z.py +11098 -0
- pyscf/gto/basis/dyall-basis/dyall_v2z.py +6472 -0
- pyscf/gto/basis/dyall-basis/dyall_v3z.py +8539 -0
- pyscf/gto/basis/dyall-basis/dyall_v4z.py +10658 -0
- pyscf/gto/basis/ma-def2-qzvp.dat +5959 -0
- pyscf/gto/basis/ma-def2-qzvpp.dat +6195 -0
- pyscf/gto/basis/ma-def2-svp.dat +3504 -0
- pyscf/gto/basis/ma-def2-svpp.dat +3504 -0
- pyscf/gto/basis/ma-def2-tzvp.dat +4347 -0
- pyscf/gto/basis/ma-def2-tzvpp.dat +4549 -0
- pyscf/gto/basis/parse_cp2k.py +8 -7
- pyscf/gto/basis/parse_cp2k_pp.py +1 -1
- pyscf/gto/basis/parse_nwchem.py +26 -11
- pyscf/gto/basis/parse_nwchem_ecp.py +2 -1
- pyscf/gto/basis/sap_grasp_large.dat +2438 -0
- pyscf/gto/basis/sap_grasp_small.dat +1434 -0
- pyscf/gto/eval_gto.py +1 -1
- pyscf/gto/ft_ao.py +6 -6
- pyscf/gto/mole.py +123 -71
- pyscf/gto/moleintor.py +1 -1
- pyscf/gw/gw_ac.py +2 -2
- pyscf/gw/gw_cd.py +2 -2
- pyscf/gw/rpa.py +135 -246
- pyscf/gw/ugw_ac.py +2 -2
- pyscf/gw/urpa.py +80 -131
- pyscf/hessian/rhf.py +30 -128
- pyscf/hessian/rks.py +1 -6
- pyscf/hessian/uhf.py +28 -138
- pyscf/hessian/uks.py +1 -8
- pyscf/lib/CMakeLists.txt +6 -2
- pyscf/lib/ao2mo/nr_ao2mo.c +1 -1
- pyscf/lib/ao2mo/nrr_ao2mo.c +1 -1
- pyscf/lib/ao2mo/r_ao2mo.c +1 -1
- pyscf/lib/cc/ccsd_pack.c +1 -1
- pyscf/lib/cc/ccsd_t.c +6 -6
- pyscf/lib/cc/uccsd_t.c +4 -4
- pyscf/lib/config.h +0 -1
- pyscf/lib/config.h.in +0 -1
- pyscf/lib/deps/include/XCFun/XCFunExport.h +1 -0
- pyscf/lib/deps/include/xc.h +28 -18
- pyscf/lib/deps/include/xc_funcs.h +50 -2
- pyscf/lib/deps/include/xc_version.h +3 -3
- pyscf/lib/deps/lib/libcint.6.dylib +0 -0
- pyscf/lib/deps/lib/{libxc.12.dylib → libxc.15.dylib} +0 -0
- pyscf/lib/deps/lib/libxcfun.2.dylib +0 -0
- pyscf/lib/dft/grid_common.c +1 -1
- pyscf/lib/dft/libxc_itrf.c +10 -7
- pyscf/lib/dft/nr_numint_sparse.c +3 -3
- pyscf/lib/dft/xcfun_itrf.c +1 -1
- pyscf/lib/diis.py +2 -2
- pyscf/lib/exceptions.py +6 -0
- pyscf/lib/gto/fill_grids_int2c.c +11 -9
- pyscf/lib/gto/fill_int2e.c +7 -5
- pyscf/lib/gto/fill_r_4c.c +1 -1
- pyscf/lib/gto/ft_ao.c +1 -1
- pyscf/lib/gto/ft_ao.h +1 -1
- pyscf/lib/gto/gto.h +2 -2
- pyscf/lib/gto/nr_ecp.c +3 -2
- pyscf/lib/libagf2.dylib +0 -0
- pyscf/lib/libao2mo.dylib +0 -0
- pyscf/lib/libcc.dylib +0 -0
- pyscf/lib/libcgto.dylib +0 -0
- pyscf/lib/libcvhf.dylib +0 -0
- pyscf/lib/libdft.dylib +0 -0
- pyscf/lib/libfci.dylib +0 -0
- pyscf/lib/libmcscf.dylib +0 -0
- pyscf/lib/libmp.dylib +0 -0
- pyscf/lib/libnp_helper.dylib +0 -0
- pyscf/lib/libpbc.dylib +0 -0
- pyscf/lib/libri.dylib +0 -0
- pyscf/lib/libxc_itrf.dylib +0 -0
- pyscf/lib/libxcfun_itrf.dylib +0 -0
- pyscf/lib/linalg_helper.py +117 -198
- pyscf/lib/logger.py +2 -1
- pyscf/lib/mcscf/fci_contract.c +10 -3
- pyscf/lib/misc.py +63 -22
- pyscf/lib/mp/CMakeLists.txt +22 -0
- pyscf/lib/mp/mp2.c +518 -0
- pyscf/lib/mp/mp2.h +44 -0
- pyscf/lib/np_helper/CMakeLists.txt +1 -1
- pyscf/lib/np_helper/imatcopy.c +360 -0
- pyscf/lib/np_helper/np_helper.c +94 -0
- pyscf/lib/np_helper/np_helper.h +26 -0
- pyscf/lib/numpy_helper.py +195 -11
- pyscf/lib/pbc/nr_direct.c +2 -7
- pyscf/lib/pbc/nr_ecp.c +10 -3
- pyscf/lib/pbc/pbc.h +1 -1
- pyscf/lib/vhf/fblas.h +3 -0
- pyscf/lib/vhf/nr_sgx_direct.c +8 -6
- pyscf/lib/vhf/nr_sr_vhf.c +8 -12
- pyscf/lib/vhf/optimizer.c +2 -2
- pyscf/lib/vhf/rkb_screen.c +139 -0
- pyscf/lo/iao.py +1 -1
- pyscf/lo/ibo.py +3 -3
- pyscf/lo/pipek_jacobi.py +1 -1
- pyscf/mcscf/__init__.py +2 -2
- pyscf/mcscf/addons.py +3 -3
- pyscf/mcscf/apc.py +2 -2
- pyscf/mcscf/casci.py +13 -7
- pyscf/mcscf/chkfile.py +69 -41
- pyscf/mcscf/dmet_cas.py +2 -2
- pyscf/mcscf/mc1step.py +72 -44
- pyscf/mcscf/newton_casscf.py +5 -5
- pyscf/mcscf/ucasci.py +1 -1
- pyscf/mcscf/umc1step.py +49 -28
- pyscf/md/integrators.py +3 -3
- pyscf/mp/__init__.py +1 -0
- pyscf/mp/dfmp2.py +498 -59
- pyscf/mp/dfmp2_native.py +11 -1
- pyscf/mp/dfmp2_slow.py +133 -0
- pyscf/mp/dfump2.py +672 -0
- pyscf/mp/dfump2_native.py +9 -0
- pyscf/mp/dfump2_slow.py +161 -0
- pyscf/mp/gmp2.py +6 -47
- pyscf/mp/mp2.py +25 -10
- pyscf/mp/ump2.py +30 -24
- pyscf/pbc/adc/kadc_rhf.py +1 -1
- pyscf/pbc/adc/kadc_rhf_amplitudes.py +2 -2
- pyscf/pbc/ao2mo/eris.py +1 -1
- pyscf/pbc/cc/kccsd_rhf.py +3 -3
- pyscf/pbc/cc/kccsd_t_rhf.py +2 -2
- pyscf/pbc/ci/kcis_rhf.py +2 -2
- pyscf/pbc/df/aft.py +8 -9
- pyscf/pbc/df/aft_ao2mo.py +1 -1
- pyscf/pbc/df/df.py +85 -12
- pyscf/pbc/df/df_jk.py +6 -2
- pyscf/pbc/df/fft.py +9 -5
- pyscf/pbc/df/fft_ao2mo.py +4 -0
- pyscf/pbc/df/fft_jk.py +18 -10
- pyscf/pbc/df/ft_ao.py +4 -3
- pyscf/pbc/df/gdf_builder.py +5 -4
- pyscf/pbc/df/incore.py +2 -2
- pyscf/pbc/df/mdf.py +6 -3
- pyscf/pbc/df/mdf_jk.py +2 -1
- pyscf/pbc/df/outcore.py +10 -10
- pyscf/pbc/df/rsdf.py +2 -2
- pyscf/pbc/df/rsdf_builder.py +13 -8
- pyscf/pbc/df/rsdf_helper.py +6 -6
- pyscf/pbc/df/rsdf_jk.py +2 -1
- pyscf/pbc/dft/cdft.py +5 -5
- pyscf/pbc/dft/gen_grid.py +3 -2
- pyscf/pbc/dft/gks.py +14 -3
- pyscf/pbc/dft/kgks.py +15 -4
- pyscf/pbc/dft/krks.py +28 -10
- pyscf/pbc/dft/krks_ksymm.py +21 -9
- pyscf/pbc/dft/krkspu.py +1 -30
- pyscf/pbc/dft/krkspu_ksymm.py +0 -30
- pyscf/pbc/dft/kuks.py +30 -13
- pyscf/pbc/dft/kuks_ksymm.py +22 -10
- pyscf/pbc/dft/kukspu.py +0 -27
- pyscf/pbc/dft/kukspu_ksymm.py +0 -30
- pyscf/pbc/dft/multigrid/multigrid.py +36 -33
- pyscf/pbc/dft/multigrid/multigrid_pair.py +7 -2
- pyscf/pbc/dft/multigrid/pp.py +1 -1
- pyscf/pbc/dft/numint.py +56 -31
- pyscf/pbc/dft/rks.py +16 -24
- pyscf/pbc/dft/uks.py +21 -4
- pyscf/pbc/eph/eph_fd.py +1 -1
- pyscf/pbc/geomopt/geometric_solver.py +1 -1
- pyscf/pbc/gto/_pbcintor.py +1 -0
- pyscf/pbc/gto/cell.py +194 -23
- pyscf/pbc/gto/ecp.py +12 -12
- pyscf/pbc/gto/eval_gto.py +3 -3
- pyscf/pbc/gto/neighborlist.py +4 -1
- pyscf/pbc/gto/pseudo/pp.py +1 -1
- pyscf/pbc/gw/krgw_ac.py +4 -4
- pyscf/pbc/gw/krgw_cd.py +4 -4
- pyscf/pbc/gw/kugw_ac.py +3 -3
- pyscf/pbc/lib/kpts_helper.py +4 -3
- pyscf/pbc/lib/linalg_helper.py +1 -1
- pyscf/pbc/mp/kmp2.py +1 -1
- pyscf/pbc/mpitools/mpi.py +1 -1
- pyscf/pbc/scf/_response_functions.py +141 -34
- pyscf/pbc/scf/addons.py +15 -11
- pyscf/pbc/scf/cphf.py +1 -1
- pyscf/pbc/scf/ghf.py +1 -1
- pyscf/pbc/scf/hf.py +21 -32
- pyscf/pbc/scf/kghf.py +33 -29
- pyscf/pbc/scf/khf.py +103 -29
- pyscf/pbc/scf/khf_ksymm.py +15 -1
- pyscf/pbc/scf/krohf.py +5 -7
- pyscf/pbc/scf/kuhf.py +54 -23
- pyscf/pbc/scf/kuhf_ksymm.py +1 -1
- pyscf/pbc/scf/rsjk.py +14 -10
- pyscf/pbc/scf/scfint.py +1 -1
- pyscf/pbc/scf/stability.py +27 -15
- pyscf/pbc/scf/uhf.py +3 -1
- pyscf/pbc/symm/symmetry.py +2 -2
- pyscf/pbc/tdscf/krhf.py +238 -154
- pyscf/pbc/tdscf/krks.py +1 -45
- pyscf/pbc/tdscf/kuhf.py +319 -171
- pyscf/pbc/tdscf/kuks.py +0 -56
- pyscf/pbc/tdscf/rhf.py +116 -3
- pyscf/pbc/tdscf/rks.py +2 -1
- pyscf/pbc/tdscf/uhf.py +214 -1
- pyscf/pbc/tdscf/uks.py +2 -1
- pyscf/pbc/tools/k2gamma.py +20 -6
- pyscf/pbc/tools/lattice.py +3 -3
- pyscf/pbc/tools/pbc.py +111 -91
- pyscf/pbc/tools/pyscf_ase.py +0 -1
- pyscf/pbc/tools/pywannier90.py +1 -1
- pyscf/qmmm/mm_mole.py +1 -1
- pyscf/scf/_response_functions.py +87 -46
- pyscf/scf/_vhf.py +15 -10
- pyscf/scf/addons.py +29 -15
- pyscf/scf/cphf.py +14 -52
- pyscf/scf/dhf.py +121 -38
- pyscf/scf/dispersion.py +10 -9
- pyscf/scf/ghf.py +25 -13
- pyscf/scf/ghf_symm.py +2 -2
- pyscf/scf/hf.py +262 -30
- pyscf/scf/rohf.py +37 -5
- pyscf/scf/stability.py +142 -112
- pyscf/scf/ucphf.py +21 -16
- pyscf/scf/uhf.py +104 -61
- pyscf/sgx/sgx.py +1 -1
- pyscf/sgx/sgx_jk.py +4 -4
- pyscf/solvent/__init__.py +2 -2
- pyscf/solvent/_attach_solvent.py +2 -0
- pyscf/solvent/_ddcosmo_tdscf_grad.py +1 -1
- pyscf/solvent/cosmors.py +366 -0
- pyscf/solvent/ddcosmo.py +1 -1
- pyscf/solvent/pcm.py +4 -4
- pyscf/solvent/pol_embed.py +1 -1
- pyscf/solvent/smd.py +5 -3
- pyscf/soscf/ciah.py +3 -11
- pyscf/soscf/newton_ah.py +5 -2
- pyscf/symm/__init__.py +1 -1
- pyscf/symm/addons.py +5 -5
- pyscf/symm/geom.py +1 -5
- pyscf/tdscf/_lr_eig.py +1002 -0
- pyscf/tdscf/dhf.py +84 -87
- pyscf/tdscf/dks.py +0 -4
- pyscf/tdscf/ghf.py +139 -127
- pyscf/tdscf/gks.py +27 -25
- pyscf/tdscf/rhf.py +194 -147
- pyscf/tdscf/rks.py +26 -22
- pyscf/tdscf/uhf.py +166 -118
- pyscf/tdscf/uks.py +32 -31
- pyscf/tools/fcidump.py +3 -0
- pyscf/tools/qcschema.py +265 -0
- pyscf/x2c/sfx2c1e.py +1 -1
- pyscf/x2c/tdscf.py +41 -41
- pyscf/x2c/x2c.py +15 -11
- {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/METADATA +39 -36
- {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/NOTICE +14 -1
- {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/RECORD +348 -316
- {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/WHEEL +1 -1
- pyscf/dft/gen_libxc_param.py +0 -35
- pyscf/dft/gen_xcfun_param.py +0 -209
- pyscf/pbc/tdscf/kproxy.py +0 -189
- pyscf/pbc/tdscf/kproxy_supercell.py +0 -664
- pyscf/pbc/tdscf/krhf_slow.py +0 -300
- pyscf/pbc/tdscf/krhf_slow_gamma.py +0 -175
- pyscf/pbc/tdscf/krhf_slow_supercell.py +0 -250
- pyscf/pbc/tdscf/proxy.py +0 -39
- pyscf/pbc/tdscf/rhf_slow.py +0 -35
- pyscf/tdscf/common_slow.py +0 -799
- pyscf/tdscf/proxy.py +0 -258
- pyscf/tdscf/rhf_slow.py +0 -181
- {pyscf-2.6.2.dist-info → pyscf-2.8.0.dist-info}/LICENSE +0 -0
- {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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
91
|
+
dms = dms + dms.transpose(0,2,1)
|
|
93
92
|
|
|
94
|
-
v1ao = vresp(
|
|
95
|
-
|
|
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 +
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return
|
|
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(
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
69
|
-
|
|
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(
|
|
92
|
-
zb = zs[:,nocca*nvira:].reshape(
|
|
93
|
-
|
|
94
|
-
|
|
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((
|
|
94
|
+
v1ao = vresp(numpy.asarray((dmsa,dmsb)))
|
|
97
95
|
|
|
98
|
-
v1a = lib.einsum('xpq,
|
|
99
|
-
v1b = lib.einsum('xpq,
|
|
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) + (
|
|
116
|
-
B[i,a,j,b] = (
|
|
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
|
-
'
|
|
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.
|
|
512
|
-
wfnsymb = rhf.
|
|
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()
|
|
567
|
-
ints_b = numpy.einsum('...pq,pi,qj->...ij', ints, orbo_b.conj()
|
|
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 =
|
|
621
|
-
e_ia_b =
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
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
|
|
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
|
-
|
|
729
|
-
|
|
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
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
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
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
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
|
-
|
|
779
|
-
|
|
780
|
-
hx = numpy.hstack((
|
|
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(
|
|
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,
|
|
824
|
+
return gen_tdhf_operation(mf, None, self.singlet, self.wfnsym)
|
|
795
825
|
|
|
796
|
-
def init_guess(self, mf, nstates=None, wfnsym=None):
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
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
|
-
|
|
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
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
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(
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
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 =
|
|
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
|
|
892
|
+
x, y = z.reshape(2, -1)
|
|
844
893
|
norm = lib.norm(x)**2 - lib.norm(y)**2
|
|
845
|
-
if norm
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
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
|
|