Beispiel #1
0
    def check_sanity(self):
        lib.StreamObject.check_sanity(self)
        cell = self.cell
        if cell.dimension < 3:
            raise RuntimeError(
                'FFTDF method does not support low-dimension '
                'PBC system.  DF, MDF or AFTDF methods should '
                'be used.\nSee also examples/pbc/31-low_dimensional_pbc.py')

        if not cell.has_ecp():
            logger.warn(
                self, 'FFTDF integrals are found in all-electron '
                'calculation.  It often causes huge error.\n'
                'Recommended methods are DF or MDF. In SCF calculation, '
                'they can be initialized as\n'
                '        mf = mf.density_fit()\nor\n'
                '        mf = mf.mix_density_fit()')

        if cell.ke_cutoff is None:
            ke_cutoff = tools.gs_to_cutoff(cell.lattice_vectors(),
                                           self.gs).min()
        else:
            ke_cutoff = numpy.min(cell.ke_cutoff)
        ke_guess = estimate_ke_cutoff(cell, cell.precision)
        if ke_cutoff < ke_guess * .8:
            gs_guess = tools.cutoff_to_gs(cell.lattice_vectors(), ke_guess)
            logger.warn(
                self, 'ke_cutoff/gs (%g / %s) is not enough for FFTDF '
                'to get integral accuracy %g.\nCoulomb integral error '
                'is ~ %.2g Eh.\nRecomended ke_cutoff/gs are %g / %s.',
                ke_cutoff, self.gs, cell.precision,
                error_for_ke_cutoff(cell, ke_cutoff), ke_guess, gs_guess)
        return self
Beispiel #2
0
    def __init__(self, cell, kpts=numpy.zeros((1, 3))):
        self.cell = cell
        self.stdout = cell.stdout
        self.verbose = cell.verbose
        self.max_memory = cell.max_memory

        self.kpts = kpts  # default is gamma point
        self.kpts_band = None
        self.auxbasis = None
        if cell.dimension == 0:
            self.eta = 0.2
            self.gs = cell.gs
        else:
            ke_cutoff = tools.gs_to_cutoff(cell.lattice_vectors(), cell.gs)
            ke_cutoff = ke_cutoff[:cell.dimension].min()
            self.eta = min(
                aft.estimate_eta_for_ke_cutoff(cell, ke_cutoff,
                                               cell.precision),
                estimate_eta(cell, cell.precision))
            ke_cutoff = aft.estimate_ke_cutoff_for_eta(cell, self.eta,
                                                       cell.precision)
            self.gs = tools.cutoff_to_gs(cell.lattice_vectors(), ke_cutoff)
            self.gs[cell.dimension:] = cell.gs[cell.dimension:]

# Not input options
        self.exxdiv = None  # to mimic KRHF/KUHF object in function get_coulG
        self.auxcell = None
        self.blockdim = 240
        self.linear_dep_threshold = LINEAR_DEP_THR
        self._j_only = False
        # If _cderi_to_save is specified, the 3C-integral tensor will be saved in this file.
        self._cderi_to_save = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR)
        # If _cderi is specified, the 3C-integral tensor will be read from this file
        self._cderi = None
        self._keys = set(self.__dict__.keys())
Beispiel #3
0
    def check_sanity(self):
        lib.StreamObject.check_sanity(self)
        cell = self.cell
        if not cell.has_ecp():
            logger.warn(
                self, 'FFTDF integrals are found in all-electron '
                'calculation.  It often causes huge error.\n'
                'Recommended methods are DF or MDF. In SCF calculation, '
                'they can be initialized as\n'
                '        mf = mf.density_fit()\nor\n'
                '        mf = mf.mix_density_fit()')

        if cell.dimension > 0:
            if cell.ke_cutoff is None:
                ke_cutoff = tools.gs_to_cutoff(cell.lattice_vectors(), self.gs)
                ke_cutoff = ke_cutoff[:cell.dimension].min()
            else:
                ke_cutoff = numpy.min(cell.ke_cutoff)
            ke_guess = estimate_ke_cutoff(cell, cell.precision)
            if ke_cutoff < ke_guess * .8:
                gs_guess = tools.cutoff_to_gs(cell.lattice_vectors(), ke_guess)
                logger.warn(
                    self, 'ke_cutoff/gs (%g / %s) is not enough for FFTDF '
                    'to get integral accuracy %g.\nCoulomb integral error '
                    'is ~ %.2g Eh.\nRecomended ke_cutoff/gs are %g / %s.',
                    ke_cutoff, self.gs, cell.precision,
                    error_for_ke_cutoff(cell, ke_cutoff), ke_guess, gs_guess)
        else:
            gs_guess = numpy.copy(self.gs)

        if cell.dimension < 3:
            err = numpy.exp(-0.87278467 * min(self.gs[cell.dimension:]) -
                            2.99944305)
            err *= cell.nelectron
            if err > cell.precision * 10:
                gz = numpy.log(
                    cell.nelectron / cell.precision) / 0.8727847 - 3.4366358
                gs_guess[cell.dimension:] = int(gz)
                logger.warn(
                    self, 'gs %s of AFTDF may not be enough to get '
                    'integral accuracy %g for %dD PBC system.\n'
                    'Coulomb integral error is ~ %.2g Eh.\n'
                    'Recomended gs is %s.', self.gs, cell.precision,
                    cell.dimension, err, gs_guess)
        return self
Beispiel #4
0
def get_nuc(mydf, kpts=None):
    cell = mydf.cell
    if kpts is None:
        kpts_lst = numpy.zeros((1, 3))
    else:
        kpts_lst = numpy.reshape(kpts, (-1, 3))

    log = logger.Logger(mydf.stdout, mydf.verbose)
    t1 = (time.clock(), time.time())

    nkpts = len(kpts_lst)
    nao = cell.nao_nr()
    nao_pair = nao * (nao + 1) // 2

    Gv, Gvbase, kws = cell.get_Gv_weights(mydf.gs)
    kpt_allow = numpy.zeros(3)
    if mydf.eta == 0:
        vpplocG = pseudo.pp_int.get_gth_vlocG_part1(cell, Gv)
        vpplocG = -numpy.einsum('ij,ij->j', cell.get_SI(Gv), vpplocG)
        vpplocG *= kws
        vG = vpplocG
        vj = numpy.zeros((nkpts, nao_pair), dtype=numpy.complex128)
    else:
        if cell.dimension > 0:
            ke_guess = estimate_ke_cutoff_for_eta(cell, mydf.eta,
                                                  cell.precision)
            gs_guess = tools.cutoff_to_gs(cell.lattice_vectors(), ke_guess)
            if numpy.any(mydf.gs < gs_guess * .8):
                logger.warn(
                    mydf, 'gs %s is not enough for AFTDF.get_nuc function '
                    'to get integral accuracy %g.\nRecomended gs is %s.',
                    mydf.gs, cell.precision, gs_guess)

        nuccell = copy.copy(cell)
        half_sph_norm = .5 / numpy.sqrt(numpy.pi)
        norm = half_sph_norm / gto.mole._gaussian_int(2, mydf.eta)
        chg_env = [mydf.eta, norm]
        ptr_eta = cell._env.size
        ptr_norm = ptr_eta + 1
        chg_bas = [[ia, 0, 1, 1, 0, ptr_eta, ptr_norm, 0]
                   for ia in range(cell.natm)]
        nuccell._atm = cell._atm
        nuccell._bas = numpy.asarray(chg_bas, dtype=numpy.int32)
        nuccell._env = numpy.hstack((cell._env, chg_env))

        # PP-loc part1 is handled by fakenuc in _int_nuc_vloc
        vj = lib.asarray(mydf._int_nuc_vloc(nuccell, kpts_lst))
        t1 = log.timer_debug1('vnuc pass1: analytic int', *t1)

        charge = -cell.atom_charges()
        coulG = tools.get_coulG(cell, kpt_allow, gs=mydf.gs, Gv=Gv)
        coulG *= kws
        aoaux = ft_ao.ft_ao(nuccell, Gv)
        vG = numpy.einsum('i,xi->x', charge, aoaux) * coulG

    max_memory = max(2000, mydf.max_memory - lib.current_memory()[0])
    for aoaoks, p0, p1 in mydf.ft_loop(mydf.gs,
                                       kpt_allow,
                                       kpts_lst,
                                       max_memory=max_memory,
                                       aosym='s2'):
        for k, aoao in enumerate(aoaoks):
            # rho_ij(G) nuc(-G) / G^2
            # = [Re(rho_ij(G)) + Im(rho_ij(G))*1j] [Re(nuc(G)) - Im(nuc(G))*1j] / G^2
            if gamma_point(kpts_lst[k]):
                vj[k] += numpy.einsum('k,kx->x', vG[p0:p1].real, aoao.real)
                vj[k] += numpy.einsum('k,kx->x', vG[p0:p1].imag, aoao.imag)
            else:
                vj[k] += numpy.einsum('k,kx->x', vG[p0:p1].conj(), aoao)
    t1 = log.timer_debug1('contracting Vnuc', *t1)

    vj_kpts = []
    for k, kpt in enumerate(kpts_lst):
        if gamma_point(kpt):
            vj_kpts.append(lib.unpack_tril(vj[k].real.copy()))
        else:
            vj_kpts.append(lib.unpack_tril(vj[k]))

    if kpts is None or numpy.shape(kpts) == (3, ):
        vj_kpts = vj_kpts[0]
    return numpy.asarray(vj_kpts)