Exemple #1
0
    def test_gen_rhf_response(self):
        numpy.random.seed(9)
        dm1 = numpy.random.random(dm_he.shape)
        dm1 = dm1 + dm1.transpose(0,2,1)
        dm1[1] = dm1[0]
        mydf = df.FFTDF(cell_he)
        ni = dft.numint.KNumInt()

        mf = dft.KRKS(cell_he)
        mf.with_df = multigrid.MultiGridFFTDF(cell_he)
        mf.kpts = kpts

        mf.xc = 'lda,'
        ref = dft.numint.nr_rks_fxc(ni, cell_he, mydf.grids, mf.xc, dm_he, dm1,
                                    kpts=kpts)
        vj = mydf.get_jk(dm1, with_k=False, kpts=kpts)[0]
        ref += vj
        v = multigrid._gen_rhf_response(mf, dm_he)(dm1)
        self.assertEqual(ref.dtype, v.dtype)
        self.assertEqual(ref.shape, v.shape)
        self.assertAlmostEqual(abs(v-ref).max(), 0, 9)

        mf.xc = 'b88,'
        ref = dft.numint.nr_rks_fxc(ni, cell_he, mydf.grids, mf.xc, dm_he, dm1,
                                    kpts=kpts)
        ref += vj
        v = multigrid._gen_rhf_response(mf, dm_he, hermi=1)(dm1)
        self.assertEqual(ref.dtype, v.dtype)
        self.assertEqual(ref.shape, v.shape)
        self.assertAlmostEqual(abs(v-ref).max(), 0, 6)
Exemple #2
0
    def test_gen_rhf_response(self):
        numpy.random.seed(9)
        dm1 = numpy.random.random(dm_he.shape)
        dm1 = dm1 + dm1.transpose(0, 2, 1)
        dm1[1] = dm1[0]
        mydf = df.FFTDF(cell_he)
        ni = dft.numint.KNumInt()

        mf = dft.KRKS(cell_he)
        mf.with_df = multigrid.MultiGridFFTDF(cell_he)
        mf.kpts = kpts

        mf.xc = 'lda,'
        ref = dft.numint.nr_rks_fxc(ni,
                                    cell_he,
                                    mydf.grids,
                                    mf.xc,
                                    dm_he,
                                    dm1,
                                    hermi=1,
                                    kpts=kpts)
        vj = mydf.get_jk(dm1, with_k=False, kpts=kpts)[0]
        ref += vj
        v = multigrid._gen_rhf_response(mf, dm_he, hermi=1)(dm1)
        self.assertEqual(ref.dtype, v.dtype)
        self.assertEqual(ref.shape, v.shape)
        self.assertAlmostEqual(abs(v - ref).max(), 0, 9)

        mf.xc = 'b88,'
        ref = dft.numint.nr_rks_fxc(ni,
                                    cell_he,
                                    mydf.grids,
                                    mf.xc,
                                    dm_he,
                                    dm1,
                                    hermi=1,
                                    kpts=kpts)
        ref += vj
        v = multigrid._gen_rhf_response(mf, dm_he, hermi=1)(dm1)
        self.assertEqual(ref.dtype, v.dtype)
        self.assertEqual(ref.shape, v.shape)
        self.assertAlmostEqual(abs(v - ref).max(), 0, 6)
Exemple #3
0
def _gen_rhf_response(mf,
                      mo_coeff=None,
                      mo_occ=None,
                      singlet=None,
                      hermi=0,
                      max_memory=None):
    assert (not isinstance(mf, (uhf.UHF, rohf.ROHF)))

    if mo_coeff is None: mo_coeff = mf.mo_coeff
    if mo_occ is None: mo_occ = mf.mo_occ
    mol = mf.mol
    if _is_dft_object(mf):
        from pyscf.dft import rks
        from pyscf.dft import numint
        ni = mf._numint
        ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True)
        if getattr(mf, 'nlc', '') != '':
            logger.warn(
                mf, 'NLC functional found in DFT object.  Its second '
                'deriviative is not available. Its contribution is '
                'not included in the response function.')
        omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, mol.spin)
        hybrid = abs(hyb) > 1e-10

        # mf can be pbc.dft.RKS object with multigrid
        if (not hybrid and 'MultiGridFFTDF' == getattr(
                mf, 'with_df', None).__class__.__name__):
            from pyscf.pbc.dft import multigrid
            dm0 = mf.make_rdm1(mo_coeff, mo_occ)
            return multigrid._gen_rhf_response(mf, dm0, singlet, hermi)

        if singlet is None:  # for newton solver
            rho0, vxc, fxc = ni.cache_xc_kernel(mol, mf.grids, mf.xc, mo_coeff,
                                                mo_occ, 0)
        else:
            rho0, vxc, fxc = ni.cache_xc_kernel(mol,
                                                mf.grids,
                                                mf.xc, [mo_coeff] * 2,
                                                [mo_occ * .5] * 2,
                                                spin=1)
        dm0 = None  #mf.make_rdm1(mo_coeff, mo_occ)

        if max_memory is None:
            mem_now = lib.current_memory()[0]
            max_memory = max(2000, mf.max_memory * .8 - mem_now)

        if singlet is None:  # Without specify singlet, general case

            def vind(dm1):
                # The singlet hessian
                if hermi == 2:
                    v1 = numpy.zeros_like(dm1)
                else:
                    v1 = ni.nr_rks_fxc(mol,
                                       mf.grids,
                                       mf.xc,
                                       dm0,
                                       dm1,
                                       0,
                                       hermi,
                                       rho0,
                                       vxc,
                                       fxc,
                                       max_memory=max_memory)
                if hybrid:
                    if hermi != 2:
                        vj, vk = mf.get_jk(mol, dm1, hermi=hermi)
                        vk *= hyb
                        if abs(omega) > 1e-10:  # For range separated Coulomb
                            vk += mf.get_k(mol, dm1, hermi,
                                           omega) * (alpha - hyb)
                        v1 += vj - .5 * vk
                    else:
                        v1 -= .5 * hyb * mf.get_k(mol, dm1, hermi=hermi)
                elif hermi != 2:
                    v1 += mf.get_j(mol, dm1, hermi=hermi)
                return v1

        elif singlet:

            def vind(dm1):
                if hermi == 2:
                    v1 = numpy.zeros_like(dm1)
                else:
                    # nr_rks_fxc_st requires alpha of dm1, dm1*.5 should be scaled
                    v1 = numint.nr_rks_fxc_st(ni,
                                              mol,
                                              mf.grids,
                                              mf.xc,
                                              dm0,
                                              dm1,
                                              0,
                                              True,
                                              rho0,
                                              vxc,
                                              fxc,
                                              max_memory=max_memory)
                    v1 *= .5
                if hybrid:
                    if hermi != 2:
                        vj, vk = mf.get_jk(mol, dm1, hermi=hermi)
                        vk *= hyb
                        if abs(omega) > 1e-10:  # For range separated Coulomb
                            vk += mf.get_k(mol, dm1, hermi,
                                           omega) * (alpha - hyb)
                        v1 += vj - .5 * vk
                    else:
                        v1 -= .5 * hyb * mf.get_k(mol, dm1, hermi=hermi)
                elif hermi != 2:
                    v1 += mf.get_j(mol, dm1, hermi=hermi)
                return v1
        else:  # triplet

            def vind(dm1):
                if hermi == 2:
                    v1 = numpy.zeros_like(dm1)
                else:
                    # nr_rks_fxc_st requires alpha of dm1, dm1*.5 should be scaled
                    v1 = numint.nr_rks_fxc_st(ni,
                                              mol,
                                              mf.grids,
                                              mf.xc,
                                              dm0,
                                              dm1,
                                              0,
                                              False,
                                              rho0,
                                              vxc,
                                              fxc,
                                              max_memory=max_memory)
                    v1 *= .5
                if hybrid:
                    vk = mf.get_k(mol, dm1, hermi=hermi)
                    vk *= hyb
                    if abs(omega) > 1e-10:  # For range separated Coulomb
                        vk += mf.get_k(mol, dm1, hermi, omega) * (alpha - hyb)
                    v1 += -.5 * vk
                return v1

    else:  # HF
        if (singlet is None or singlet) and hermi != 2:

            def vind(dm1):
                vj, vk = mf.get_jk(mol, dm1, hermi=hermi)
                return vj - .5 * vk
        else:

            def vind(dm1):
                return -.5 * mf.get_k(mol, dm1, hermi=hermi)

    return vind
Exemple #4
0
    def test_nr_rks_fxc_st(self):
        numpy.random.seed(9)
        dm1 = numpy.random.random(
            dm_he.shape) + numpy.random.random(dm_he.shape) * 1j
        dm1[1] = dm1[0]
        mydf = df.FFTDF(cell_he)
        ni = dft.numint.KNumInt()
        mg_df = multigrid.MultiGridFFTDF(cell_he)

        mf = dft.KRKS(cell_he)
        mf.with_df = mg_df
        mf.kpts = kpts

        xc = 'lda,'
        ref = dft.numint.nr_rks_fxc_st(ni,
                                       cell_he,
                                       mydf.grids,
                                       xc,
                                       dm_he,
                                       dm1,
                                       singlet=True,
                                       kpts=kpts)
        v = multigrid.nr_rks_fxc_st(mg_df,
                                    xc,
                                    dm_he,
                                    dm1,
                                    singlet=True,
                                    kpts=kpts)
        self.assertEqual(ref.dtype, v.dtype)
        self.assertEqual(ref.shape, v.shape)
        self.assertAlmostEqual(abs(v - ref).max(), 0, 4)

        mf.xc = 'b88,'
        ref = dft.numint.nr_rks_fxc_st(ni,
                                       cell_he,
                                       mydf.grids,
                                       mf.xc,
                                       dm_he,
                                       dm1,
                                       singlet=True,
                                       kpts=kpts)
        v = multigrid._gen_rhf_response(mf, dm_he, singlet=True)(dm1)
        self.assertEqual(ref.dtype, v.dtype)
        self.assertEqual(ref.shape, v.shape)
        self.assertAlmostEqual(abs(v - ref).max(), 0, 5)

        mf.xc = 'lda,'
        ref = dft.numint.nr_rks_fxc_st(ni,
                                       cell_he,
                                       mydf.grids,
                                       mf.xc,
                                       dm_he,
                                       dm1,
                                       singlet=False,
                                       kpts=kpts)
        v = multigrid._gen_rhf_response(mf, dm_he, singlet=False)(dm1)
        self.assertEqual(ref.dtype, v.dtype)
        self.assertEqual(ref.shape, v.shape)
        self.assertAlmostEqual(abs(v - ref).max(), 0, 4)

        xc = 'b88,'
        ref = dft.numint.nr_rks_fxc_st(ni,
                                       cell_he,
                                       mydf.grids,
                                       xc,
                                       dm_he,
                                       dm1,
                                       singlet=False,
                                       kpts=kpts)
        v = multigrid.nr_rks_fxc_st(mg_df,
                                    xc,
                                    dm_he,
                                    dm1,
                                    singlet=False,
                                    kpts=kpts)
        self.assertEqual(ref.dtype, v.dtype)
        self.assertEqual(ref.shape, v.shape)
        self.assertAlmostEqual(abs(v - ref).max(), 0, 5)
Exemple #5
0
def _gen_rhf_response(mf,
                      mo_coeff=None,
                      mo_occ=None,
                      singlet=None,
                      hermi=0,
                      max_memory=None):
    from pyscf.pbc.dft import numint, multigrid
    assert (isinstance(mf, khf.KRHF))

    if mo_coeff is None: mo_coeff = mf.mo_coeff
    if mo_occ is None: mo_occ = mf.mo_occ
    cell = mf.cell
    kpts = mf.kpts
    if getattr(mf, 'xc', None) and getattr(mf, '_numint', None):
        ni = mf._numint
        ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True)

        omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, spin=cell.spin)
        hybrid = abs(hyb) > 1e-10
        if abs(omega) > 1e-10:  # For range separated Coulomb
            raise NotImplementedError

        if not hybrid and isinstance(mf.with_df, multigrid.MultiGridFFTDF):
            dm0 = mf.make_rdm1(mo_coeff, mo_occ)
            return multigrid._gen_rhf_response(mf, dm0, singlet, hermi)

        if singlet is None:  # for newton solver
            rho0, vxc, fxc = ni.cache_xc_kernel(cell, mf.grids, mf.xc,
                                                mo_coeff, mo_occ, 0, kpts)
        else:
            if isinstance(mo_occ, numpy.ndarray):
                mo_occ = mo_occ * .5
            else:
                mo_occ = [x * .5 for x in mo_occ]
            rho0, vxc, fxc = ni.cache_xc_kernel(cell,
                                                mf.grids,
                                                mf.xc, [mo_coeff] * 2,
                                                [mo_occ] * 2,
                                                spin=1,
                                                kpts=kpts)
        dm0 = None  #mf.make_rdm1(mo_coeff, mo_occ)

        if max_memory is None:
            mem_now = lib.current_memory()[0]
            max_memory = max(2000, mf.max_memory * .8 - mem_now)

        if singlet is None:  # Without specify singlet, general case

            def vind(dm1):
                # The singlet hessian
                if hermi == 2:
                    v1 = numpy.zeros_like(dm1)
                else:
                    v1 = ni.nr_rks_fxc(cell,
                                       mf.grids,
                                       mf.xc,
                                       dm0,
                                       dm1,
                                       0,
                                       hermi,
                                       rho0,
                                       vxc,
                                       fxc,
                                       kpts,
                                       max_memory=max_memory)
                if hybrid:
                    if hermi != 2:
                        vj, vk = mf.get_jk(cell, dm1, hermi=hermi, kpts=kpts)
                        v1 += vj - .5 * hyb * vk
                    else:
                        v1 -= .5 * hyb * mf.get_k(
                            cell, dm1, hermi=hermi, kpts=kpts)
                elif hermi != 2:
                    v1 += mf.get_j(cell, dm1, hermi=hermi, kpts=kpts)
                return v1

        elif singlet:

            def vind(dm1):
                if hermi == 2:
                    v1 = numpy.zeros_like(dm1)
                else:
                    # nr_rks_fxc_st requires alpha of dm1
                    v1 = numint.nr_rks_fxc_st(ni,
                                              cell,
                                              mf.grids,
                                              mf.xc,
                                              dm0,
                                              dm1,
                                              0,
                                              True,
                                              rho0,
                                              vxc,
                                              fxc,
                                              kpts,
                                              max_memory=max_memory)
                    v1 *= .5
                if hybrid:
                    if hermi != 2:
                        vj, vk = mf.get_jk(cell, dm1, hermi=hermi, kpts=kpts)
                        v1 += vj - .5 * hyb * vk
                    else:
                        v1 -= .5 * hyb * mf.get_k(
                            cell, dm1, hermi=hermi, kpts=kpts)
                elif hermi != 2:
                    v1 += mf.get_j(cell, dm1, hermi=hermi, kpts=kpts)
                return v1
        else:  # triplet

            def vind(dm1):
                if hermi == 2:
                    v1 = numpy.zeros_like(dm1)
                else:
                    # nr_rks_fxc_st requires alpha of dm1
                    v1 = numint.nr_rks_fxc_st(ni,
                                              cell,
                                              mf.grids,
                                              mf.xc,
                                              dm0,
                                              dm1,
                                              0,
                                              False,
                                              rho0,
                                              vxc,
                                              fxc,
                                              kpts,
                                              max_memory=max_memory)
                    v1 *= .5
                if hybrid:
                    v1 += -.5 * hyb * mf.get_k(
                        cell, dm1, hermi=hermi, kpts=kpts)
                return v1

    else:  # HF
        if (singlet is None or singlet) and hermi != 2:

            def vind(dm1):
                vj, vk = mf.get_jk(cell, dm1, hermi=hermi, kpts=kpts)
                return vj - .5 * vk
        else:

            def vind(dm1):
                return -.5 * mf.get_k(cell, dm1, hermi=hermi, kpts=kpts)

    return vind
Exemple #6
0
def _gen_rhf_response(mf, mo_coeff=None, mo_occ=None,
                      singlet=None, hermi=0, max_memory=None):
    assert(not isinstance(mf, (uhf.UHF, rohf.ROHF)))

    if mo_coeff is None: mo_coeff = mf.mo_coeff
    if mo_occ is None: mo_occ = mf.mo_occ
    mol = mf.mol
    if getattr(mf, 'xc', None) and getattr(mf, '_numint', None):
        from pyscf.dft import rks
        from pyscf.dft import numint
        ni = mf._numint
        ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True)
        if getattr(mf, 'nlc', '') != '':
            logger.warn(mf, 'NLC functional found in DFT object.  Its second '
                        'deriviative is not available. Its contribution is '
                        'not included in the response function.')
        omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, mol.spin)
        hybrid = abs(hyb) > 1e-10

        # mf can be pbc.dft.RKS object with multigrid
        if (not hybrid and
            'MultiGridFFTDF' == getattr(mf, 'with_df', None).__class__.__name__):
            from pyscf.pbc.dft import multigrid
            dm0 = mf.make_rdm1(mo_coeff, mo_occ)
            return multigrid._gen_rhf_response(mf, dm0, singlet, hermi)

        if singlet is None:  # for newton solver
            rho0, vxc, fxc = ni.cache_xc_kernel(mol, mf.grids, mf.xc,
                                                mo_coeff, mo_occ, 0)
        else:
            rho0, vxc, fxc = ni.cache_xc_kernel(mol, mf.grids, mf.xc,
                                                [mo_coeff]*2, [mo_occ*.5]*2, spin=1)
        dm0 = None #mf.make_rdm1(mo_coeff, mo_occ)

        if max_memory is None:
            mem_now = lib.current_memory()[0]
            max_memory = max(2000, mf.max_memory*.8-mem_now)

        if singlet is None:  # Without specify singlet, general case
            def vind(dm1):
                # The singlet hessian
                if hermi == 2:
                    v1 = numpy.zeros_like(dm1)
                else:
                    v1 = ni.nr_rks_fxc(mol, mf.grids, mf.xc, dm0, dm1, 0, hermi,
                                       rho0, vxc, fxc, max_memory=max_memory)
                if hybrid:
                    if hermi != 2:
                        vj, vk = mf.get_jk(mol, dm1, hermi=hermi)
                        vk *= hyb
                        if abs(omega) > 1e-10:  # For range separated Coulomb
                            vk += rks._get_k_lr(mol, dm1, omega, hermi) * (alpha-hyb)
                        v1 += vj - .5 * vk
                    else:
                        v1 -= .5 * hyb * mf.get_k(mol, dm1, hermi=hermi)
                elif hermi != 2:
                    v1 += mf.get_j(mol, dm1, hermi=hermi)
                return v1

        elif singlet:
            def vind(dm1):
                if hermi == 2:
                    v1 = numpy.zeros_like(dm1)
                else:
                    # nr_rks_fxc_st requires alpha of dm1, dm1*.5 should be scaled
                    v1 = numint.nr_rks_fxc_st(ni, mol, mf.grids, mf.xc, dm0, dm1, 0,
                                              True, rho0, vxc, fxc,
                                              max_memory=max_memory)
                    v1 *= .5
                if hybrid:
                    if hermi != 2:
                        vj, vk = mf.get_jk(mol, dm1, hermi=hermi)
                        vk *= hyb
                        if abs(omega) > 1e-10:  # For range separated Coulomb
                            vk += rks._get_k_lr(mol, dm1, omega, hermi) * (alpha-hyb)
                        v1 += vj - .5 * vk
                    else:
                        v1 -= .5 * hyb * mf.get_k(mol, dm1, hermi=hermi)
                elif hermi != 2:
                    v1 += mf.get_j(mol, dm1, hermi=hermi)
                return v1
        else:  # triplet
            def vind(dm1):
                if hermi == 2:
                    v1 = numpy.zeros_like(dm1)
                else:
                    # nr_rks_fxc_st requires alpha of dm1, dm1*.5 should be scaled
                    v1 = numint.nr_rks_fxc_st(ni, mol, mf.grids, mf.xc, dm0, dm1, 0,
                                              False, rho0, vxc, fxc,
                                              max_memory=max_memory)
                    v1 *= .5
                if hybrid:
                    vk = mf.get_k(mol, dm1, hermi=hermi)
                    vk *= hyb
                    if abs(omega) > 1e-10:  # For range separated Coulomb
                        vk += rks._get_k_lr(mol, dm1, omega, hermi) * (alpha-hyb)
                    v1 += -.5 * vk
                return v1

    else:  # HF
        if (singlet is None or singlet) and hermi != 2:
            def vind(dm1):
                vj, vk = mf.get_jk(mol, dm1, hermi=hermi)
                return vj - .5 * vk
        else:
            def vind(dm1):
                return -.5 * mf.get_k(mol, dm1, hermi=hermi)

    return vind