Пример #1
0
    def __init__(self, bee, xcoefs, ldac, ggac):
        """BEEVDW kernel.

        parameters:

        bee : str
            choose BEE1 or BEE2 exchange basis expansion.
        xcoefs : array
            coefficients for exchange.
        ldac : float
            coefficient for LDA correlation.
        pbec : float
            coefficient for PBE correlation.

        """

        if bee == 'BEE2':
            self.BEE = BEE2(xcoefs)
            self.GGAc = LibXC('GGA_C_PBE')
            self.xtype = 'GGA'
            self.type = 'GGA'
        elif bee == 'BEE3':
            self.BEE = LibXC('MGGA_X_MBEEFVDW')
            self.GGAc = LibXC('GGA_C_PBE_SOL')
            self.xtype = 'MGGA'
            self.type = 'MGGA'
        else:
            raise ValueError('Unknown BEE exchange: %s', bee)

        self.LDAc = LibXC('LDA_C_PW')
        self.ldac = ldac
        self.ggac = ggac
        if bee in ['BEE1', 'BEE2']:
            self.ggac -= 1.0
        self.name = 'BEEVDW'
Пример #2
0
def VDWFunctional(name, fft=True, **kwargs):
    if name == 'vdW-DF':
        kernel = LibXC('GGA_X_PBE_R+LDA_C_PW')
    elif name == 'vdW-DF2':
        kernel = LibXC('GGA_X_RPW86+LDA_C_PW')
        kwargs['Zab'] = -1.887
    elif name == 'optPBE-vdW':
        kernel = LibXC('GGA_X_OPTPBE_VDW+LDA_C_PW')
    elif name == 'optB88-vdW':
        kernel = LibXC('GGA_X_OPTB88_VDW+LDA_C_PW')
    elif name == 'C09-vdW':
        kernel = LibXC('GGA_X_C09X+LDA_C_PW')
    elif name == 'BEEF-vdW':
        from gpaw.xc.bee import BEEVDWKernel
        kernel = BEEVDWKernel('BEE2', None, 0.600166476948828631066,
                              0.399833523051171368934)
        kwargs['Zab'] = -1.887
        kwargs['setup_name'] = 'PBE'
    elif name == 'mBEEF-vdW':
        from gpaw.xc.bee import BEEVDWKernel
        kernel = BEEVDWKernel('BEE3', None, 0.405258352, 0.356642240)
        kwargs['Zab'] = -1.887
        kwargs['vdwcoef'] = 0.886774972
        kwargs['Nr'] = 4096
        kwargs['setup_name'] = 'PBEsol'
        assert fft
        return MGGAFFTVDWFunctional(name, kernel, **kwargs)
    else:
        2 / 0
    if fft:
        return GGAFFTVDWFunctional(name, kernel, **kwargs)
    return GGARealSpaceVDWFunctional(name, kernel, **kwargs)
Пример #3
0
 def __init__(self, just_kidding=False):
     self.just_kidding = just_kidding
     self.type = 'GGA'
     self.lda_c = LibXC('LDA_C_PW')
     if self.just_kidding:
         self.name = 'purepython rPW86_with_%s' % self.lda_c.name
     else:
         self.name = 'purepython cx'
Пример #4
0
    def __init__(self, c=None):
        self.tb09 = LibXC('MGGA_X_TB09').xc.tb09
        self.ldac = LibXC('LDA_C_PW')

        self.fixedc = c is not None  # calculate c or use fixed value
        self.c = c  # amount of "exact exchange"
        self.n = 0  # Lebedev quadrature point number (0-49)
        self.sign = 1.0  # sign of PAW correction: +1 for AE and -1 for PS
        self.I = None  # integral from Eq. (3)
Пример #5
0
    def __init__(self, xcoefs, ldac, pbec, lyp):
        self.BEE1 = BEE1(xcoefs)
        self.LDAc = LibXC('LDA_C_PW')
        self.PBEc = LibXC('GGA_C_PBE')
        self.LYP = LibXC('GGA_C_LYP')
        self.ldac = ldac
        self.pbec = pbec
        self.lyp = lyp

        self.type = 'GGA'
        self.name = 'BEEVDW'
Пример #6
0
    def __init__(self, bee, xcoefs, ldac, ggac):
        """BEEVDW kernel.

        parameters:

        bee : str
            choose BEE1 or BEE2 exchange basis expansion.
        xcoefs : array
            coefficients for exchange.
        ldac : float
            coefficient for LDA correlation.
        pbec : float
            coefficient for PBE correlation.

        """

        if bee == 'BEE2':
            self.BEE = BEE2(xcoefs)
            self.GGAc = LibXC('GGA_C_PBE')
            self.xtype = 'GGA'
            self.type = 'GGA'
        elif bee == 'BEE3':
            self.BEE = LibXC('MGGA_X_MBEEFVDW')
            self.GGAc = LibXC('GGA_C_PBE_SOL')
            self.xtype = 'MGGA'
            self.type = 'MGGA'
        else:
            raise ValueError('Unknown BEE exchange: %s', bee)

        self.LDAc = LibXC('LDA_C_PW')
        self.ldac = ldac
        self.ggac = ggac
        if bee in ['BEE1', 'BEE2']:
            self.ggac -= 1.0
        self.name = 'BEEVDW'
Пример #7
0
def vdw_df2(**kwargs):
    kwargs1 = dict(name='vdW-DF2',
                   setup_name='PBE',
                   semilocal_xc=GGA(LibXC('GGA_X_RPW86+LDA_C_PW'),
                                    stencil=kwargs.pop('stencil', 2)))
    kwargs1.update(kwargs)
    return VDWXC(**kwargs1)
Пример #8
0
def create_xc(func, mode):
    isinstance(func, str)
    isinstance(mode, int)
    if mode == 0:
        xc = LibXC(func)
    else:
        xc = XCKernel(func)
    return xc
 def calculate(self, e_g, n_sg, dedn_sg,
               sigma_xg=None, dedsigma_xg=None,
               tau_sg=None, dedtau_sg=None):
     n_g = n_sg[0]
     m_vg = n_sg[1:4]
     m_g = (m_vg**2).sum(0)**0.5
     nnew_sg = np.empty((2,) + n_g.shape)
     nnew_sg[:] = n_g
     nnew_sg[0] += m_g
     nnew_sg[1] -= m_g
     nnew_sg *= 0.5
     vnew_sg = np.zeros_like(nnew_sg)
     LibXC.calculate(self, e_g, nnew_sg, vnew_sg)
     dedn_sg[0] += 0.5 * vnew_sg.sum(0)
     vnew_sg /= np.where(m_g < 1e-15, 1, m_g)
     dedn_sg[1:4] += 0.5 * vnew_sg[0] * m_vg
     dedn_sg[1:4] -= 0.5 * vnew_sg[1] * m_vg
Пример #10
0
def vdw_C09(**kwargs):
    kwargs1 = dict(name='vdW-C09',
                   libvdwxc_name='vdW-DF',
                   setup_name='PBE',
                   semilocal_xc=GGA(LibXC('GGA_X_C09X+LDA_C_PW'),
                                    stencil=kwargs.pop('stencil', 2)))
    kwargs1.update(kwargs)
    return VDWXC(**kwargs1)
Пример #11
0
def test_selfconsistent():
    from gpaw import GPAW
    from ase.build import molecule
    from gpaw.xc.gga import GGA

    system = molecule('H2O')
    system.center(vacuum=3.)

    def test(xc):
        calc = GPAW(
            mode='lcao',
            xc=xc,
            setups='sg15',
            txt='gpaw.%s.txt' % str(xc)  # .kernel.name
        )
        system.set_calculator(calc)
        return system.get_potential_energy()

    libxc_results = {}

    for name in ['GGA_X_PBE_R+LDA_C_PW', 'GGA_X_RPW86+LDA_C_PW']:
        xc = GGA(LibXC(name))
        e = test(xc)
        libxc_results[name] = e

    cx_gga_results = {}
    cx_gga_results['rpw86'] = test(GGA(CXGGAKernel(just_kidding=True)))
    cx_gga_results['lv_rpw86'] = test(GGA(CXGGAKernel(just_kidding=False)))

    vdw_results = {}
    vdw_coef0_results = {}

    for vdw in [vdw_df(), vdw_df2(), vdw_df_cx()]:
        vdw.vdwcoef = 0.0
        vdw_coef0_results[vdw.__class__.__name__] = test(vdw)
        vdw.vdwcoef = 1.0  # Leave nicest text file by running real calc last
        vdw_results[vdw.__class__.__name__] = test(vdw)

    from gpaw.mpi import world
    # These tests basically verify that the LDA/GGA parts of vdwdf
    # work correctly.
    if world.rank == 0:
        print('Now comparing...')
        err1 = cx_gga_results['rpw86'] - libxc_results['GGA_X_RPW86+LDA_C_PW']
        print('Our rpw86 must be identical to that of libxc. Err=%e' % err1)
        print('RPW86 interpolated with Langreth-Vosko stuff differs by %f' %
              (cx_gga_results['lv_rpw86'] - cx_gga_results['rpw86']))
        print('Each vdwdf with vdwcoef zero must yield same result as gga'
              'kernel')
        err_df1 = vdw_coef0_results['VDWDF'] - libxc_results['GGA_X_PBE_R+'
                                                             'LDA_C_PW']
        print('  df1 err=%e' % err_df1)
        err_df2 = vdw_coef0_results['VDWDF2'] - libxc_results['GGA_X_RPW86+'
                                                              'LDA_C_PW']
        print('  df2 err=%e' % err_df2)
        err_cx = vdw_coef0_results['VDWDFCX'] - cx_gga_results['lv_rpw86']
        print('   cx err=%e' % err_cx)
Пример #12
0
def XC(kernel, parameters=None):
    """Create XCFunctional object.

    kernel: XCKernel object or str
        Kernel object or name of functional.
    parameters: ndarray
        Parameters for BEE functional.

    Recognized names are: LDA, PW91, PBE, revPBE, RPBE, BLYP, HCTH407,
    TPSS, M06L, revTPSS, vdW-DF, vdW-DF2, EXX, PBE0, B3LYP, BEE,
    GLLBSC.  One can also use equivalent libxc names, for example
    GGA_X_PBE+GGA_C_PBE is equivalent to PBE, and LDA_X to the LDA exchange.
    In this way one has access to all the functionals defined in libxc.
    See gpaw.xc.libxc_functionals.py for the complete list.  """

    if isinstance(kernel, str):
        name = kernel
        if name in ['vdW-DF', 'vdW-DF2']:
            from gpaw.xc.vdw import FFTVDWFunctional
            return FFTVDWFunctional(name)
        elif name in ['EXX', 'PBE0', 'B3LYP']:
            from gpaw.xc.hybrid import HybridXC
            return HybridXC(name)
        elif name == 'BEE1':
            from gpaw.xc.bee import BEE1
            kernel = BEE1(parameters)
        elif name.startswith('GLLB'):
            from gpaw.xc.gllb.nonlocalfunctionalfactory import \
                 NonLocalFunctionalFactory
            xc = NonLocalFunctionalFactory().get_functional_by_name(name)
            xc.print_functional()
            return xc
        elif name == 'LB94':
            from gpaw.xc.lb94 import LB94
            kernel = LB94()
        elif name.startswith('ODD_'):
            from ODD import ODDFunctional
            return ODDFunctional(name[4:])
        elif name.endswith('PZ-SIC'):
            try:
                from ODD import PerdewZungerSIC as SIC
                return SIC(xc=name[:-7])
            except:
                from gpaw.xc.sic import SIC
                return SIC(xc=name[:-7])
        elif name.startswith('old'):
            from gpaw.xc.kernel import XCKernel
            kernel = XCKernel(name[3:])
        else:
            kernel = LibXC(kernel)
    if kernel.type == 'LDA':
        return LDA(kernel)
    elif kernel.type == 'GGA':
        return GGA(kernel)
    else:
        return MGGA(kernel)
Пример #13
0
 def __init__(self, name):
     self.name = name
     self.kernels = []
     self.coefs = []
     self.type = 'LDA'
     for x in name.split('+'):
         c, n = x.split('_', 1)
         self.coefs.append(float(c))
         kernel = LibXC(n)
         self.kernels.append(kernel)
         if kernel.type == 'GGA':
             self.type = 'GGA'
Пример #14
0
def vdw_df_cx(**kwargs):
    # cx semilocal exchange is in libxc 2.2.2 or newer (or maybe from older)
    kernel = kwargs.get('kernel')
    if kernel is None:
        kernel = LibXC('GGA_X_LV_RPW86+LDA_C_PW')

    kwargs1 = dict(
        name='vdW-DF-cx',
        setup_name='PBE',
        # PBEsol is most correct but not distributed by default.
        semilocal_xc=GGA(kernel, stencil=kwargs.pop('stencil', 2)))
    kwargs1.update(kwargs)
    return VDWXC(**kwargs1)
Пример #15
0
 def calculate(self,
               e_g,
               n_sg,
               dedn_sg,
               sigma_xg=None,
               dedsigma_xg=None,
               tau_sg=None,
               dedtau_sg=None):
     n_g = n_sg[0]
     m_vg = n_sg[1:4]
     m_g = (m_vg**2).sum(0)**0.5
     nnew_sg = np.empty((2, ) + n_g.shape)
     nnew_sg[:] = n_g
     nnew_sg[0] += m_g
     nnew_sg[1] -= m_g
     nnew_sg *= 0.5
     vnew_sg = np.zeros_like(nnew_sg)
     LibXC.calculate(self, e_g, nnew_sg, vnew_sg)
     dedn_sg[0] += 0.5 * vnew_sg.sum(0)
     vnew_sg /= np.where(m_g < 1e-15, 1, m_g)
     dedn_sg[1:4] += 0.5 * vnew_sg[0] * m_vg
     dedn_sg[1:4] -= 0.5 * vnew_sg[1] * m_vg
Пример #16
0
def vdw_df_cx(*args, **kwargs):
    try:
        # Exists in libxc 2.2.2 or newer (or maybe from older)
        kernel = LibXC('GGA_X_LV_RPW86+LDA_C_PW')
    except NameError:
        kernel = CXGGAKernel()

    # Hidden debug feature
    if kwargs.get('gga_backend') == 'purepython':
        kernel = CXGGAKernel()
        kwargs.pop('gga_backend')
    assert 'gga_backend' not in kwargs

    return VDWXC(semilocal_xc=GGA(kernel), name='vdW-DF-CX', *args, **kwargs)
Пример #17
0
def test_derivatives():
    gen = np.random.RandomState(1)
    shape = (1, 20, 20, 20)
    ngpts = np.product(shape)
    n_sg = gen.rand(*shape)
    sigma_xg = np.zeros(shape)
    sigma_xg[:] = gen.rand(*shape)

    qe_kernel = CXGGAKernel(just_kidding=True)
    libxc_kernel = LibXC('GGA_X_RPW86+LDA_C_PW')

    cx_kernel = CXGGAKernel(just_kidding=False)

    def check(kernel, n_sg, sigma_xg):
        e_g = np.zeros(shape[1:])
        dedn_sg = np.zeros(shape)
        dedsigma_xg = np.zeros(shape)
        kernel.calculate(e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg)
        return e_g, dedn_sg, dedsigma_xg

    def check_and_write(kernel):
        n1_sg = n_sg.copy()
        e_g, dedn_sg, dedsigma_xg = check(kernel, n_sg, sigma_xg)
        dedn = dedn_sg[0, 0, 0, 0]
        dedsigma = dedsigma_xg[0, 0, 0, 0]

        dn = 1e-6
        n1_sg = n_sg.copy()
        n1_sg[0, 0, 0, 0] -= dn / 2.
        e1_g, _, _ = check(kernel, n1_sg, sigma_xg)

        n1_sg[0, 0, 0, 0] += dn
        e2_g, _, _ = check(kernel, n1_sg, sigma_xg)

        dedn_fd = (e2_g[0, 0, 0] - e1_g[0, 0, 0]) / dn
        dedn_err = abs(dedn - dedn_fd)

        print('e', e_g.sum() / ngpts)
        print('dedn', dedn, 'fd', dedn_fd, 'err %e' % dedn_err)

        sigma1_xg = sigma_xg.copy()
        sigma1_xg[0, 0, 0, 0] -= dn / 2.
        e1s_g, _, _ = check(kernel, n_sg, sigma1_xg)

        sigma1_xg[0, 0, 0, 0] += dn
        e2s_g, _, _ = check(kernel, n_sg, sigma1_xg)

        dedsigma_fd = (e2s_g[0, 0, 0] - e1s_g[0, 0, 0]) / dn
        dedsigma_err = dedsigma - dedsigma_fd

        print('dedsigma', dedsigma, 'fd', dedsigma_fd, 'err %e' % dedsigma_err)
        return e_g, dedn_sg, dedsigma_xg

    print('pw86r libxc')
    e_lxc_g, dedn_lxc_g, dedsigma_lxc_g = check_and_write(libxc_kernel)
    print()
    print('pw86r ours')
    e_qe_g, dedn_qe_g, dedsigma_qe_g = check_and_write(qe_kernel)
    print()
    print('cx')
    check_and_write(cx_kernel)

    print()
    print('lxc vs qe discrepancies')
    print('=======================')
    e_err = np.abs(e_lxc_g - e_qe_g).max()
    print('e', e_err)
    dedn_err = np.abs(dedn_qe_g - dedn_lxc_g).max()
    dedsigma_err = np.abs(dedsigma_lxc_g - dedsigma_qe_g).max()
    print('dedn', dedn_err)
    print('dedsigma', dedsigma_err)
Пример #18
0
class CXGGAKernel:
    def __init__(self, just_kidding=False):
        self.just_kidding = just_kidding
        self.type = 'GGA'
        self.lda_c = LibXC('LDA_C_PW')
        if self.just_kidding:
            self.name = 'purepython rPW86_with_%s' % self.lda_c.name
        else:
            self.name = 'purepython cx'

    def calculate(self, e_g, n_sg, v_sg, sigma_xg, dedsigma_xg):
        e_g[:] = 0.0
        dedsigma_xg[:] = 0.0

        self.lda_c.calculate(e_g, n_sg, v_sg, sigma_xg, dedsigma_xg)

        for arr in [n_sg, v_sg, sigma_xg, dedsigma_xg]:
            assert len(arr) == 1
        self._exchange(n_sg[0], sigma_xg[0], e_g, v_sg[0], dedsigma_xg[0])

    def _exchange(self, rho, grho, sx, v1x, v2x):
        """Calculate cx local exchange.

        Note that this *adds* to the energy density sx so that it can
        be called after LDA correlation part without ruining anything.
        Also it adds to v1x and v2x as is normal in GPAW."""
        tol = 1e-20
        rho[rho < tol] = tol
        grho[grho < tol] = tol
        alp = 0.021789
        beta = 1.15
        a = 1.851
        b = 17.33
        c = 0.163
        mu_LM = 0.09434
        s_prefactor = 6.18733545256027
        Ax = -0.738558766382022  # = -3./4. * (3./pi)**(1./3)
        four_thirds = 4. / 3.

        grad_rho = np.sqrt(grho)

        # eventually we need s to power 12.  Clip to avoid overflow
        # (We have individual tolerances on both rho and grho, but
        # they are not sufficient to guarantee this)
        s_1 = (grad_rho / (s_prefactor * rho**four_thirds)).clip(0.0, 1e20)
        s_2 = s_1 * s_1
        s_3 = s_2 * s_1
        s_4 = s_3 * s_1
        s_5 = s_4 * s_1
        s_6 = s_5 * s_1

        fs_rPW86 = (1.0 + a * s_2 + b * s_4 + c * s_6)**(1. / 15.)

        if self.just_kidding:
            fs = fs_rPW86
        else:
            fs = (1.0 + mu_LM * s_2) / (1.0 + alp * s_6) \
                + alp * s_6 / (beta + alp * s_6) * fs_rPW86

        # the energy density for the exchange.
        sx[:] += Ax * rho**four_thirds * fs

        df_rPW86_ds = (1. / (15. * fs_rPW86**14.0)) * \
            (2 * a * s_1 + 4 * b * s_3 + 6 * c * s_5)

        if self.just_kidding:
            df_ds = df_rPW86_ds  # XXXXXXXXXXXXXXXXXXXX
        else:
            df_ds = 1. / (1. + alp * s_6)**2 \
                * (2.0 * mu_LM * s_1 * (1. + alp * s_6) -
                   6.0 * alp * s_5 * (1. + mu_LM * s_2)) \
                + alp * s_6 / (beta + alp * s_6) * df_rPW86_ds \
                + 6.0 * alp * s_5 * fs_rPW86 / (beta + alp * s_6) \
                * (1. - alp * s_6 / (beta + alp * s_6))

        # de/dn.  This is the partial derivative of sx wrt. n, for s constant
        v1x[:] += Ax * four_thirds * (rho**(1. / 3.) * fs - grad_rho /
                                      (s_prefactor * rho) * df_ds)
        # de/d(nabla n).  The other partial derivative
        v2x[:] += 0.5 * Ax * df_ds / (s_prefactor * grad_rho)
Пример #19
0
    def __init__(self, world=None, Zab=-0.8491, vdwcoef=1.0, q0cut=5.0,
                 phi0=0.5, ds=1.0, Dmax=20.0, nD=201, ndelta=21,
                 soft_correction=False, setup_name='revPBE',
                 verbose=False, energy_only=False):
        """vdW-DF.

        parameters:

        name: str
            Name of functional.
        world: MPI communicator
            Communicator to parallelize over.  Defaults to gpaw.mpi.world.
        q0cut: float
            Maximum value for q0.
        phi0: float
            Smooth value for phi(0,0).
        ds: float
            Cutoff for smooth kernel.
        Dmax: float
            Maximum value for D.
        nD: int
            Number of values for D in kernel-table.
        ndelta: int
            Number of values for delta in kernel-table.
        soft_correction: bool
            Correct for soft kernel.
        kernel:
            Which kernel to use.
        Zab:
            parameter in nonlocal kernel.
        vdwcoef: float
            Scaling of vdW energy.
        verbose: bool
            Print useful information.
        """
        
        if world is None:
            self.world = mpi.world
        else:
            self.world = world

        self.Zab = Zab
        self.vdwcoef = vdwcoef
        self.q0cut = q0cut
        self.phi0 = phi0
        self.ds = ds

        self.delta_i = np.linspace(0, 1.0, ndelta)
        self.D_j = np.linspace(0, Dmax, nD)

        self.verbose = verbose
        
        self.read_table()

        self.soft_correction = soft_correction
        if soft_correction:
            dD = self.D_j[1]
            self.C_soft = np.dot(self.D_j**2, self.phi_ij[0]) * 4 * pi * dD
            
        self.gd = None
        self.energy_only = energy_only
        self.timer = nulltimer

        self.LDAc = LibXC('LDA_C_PW')
        self.setup_name = setup_name
 def __init__(self):
     LibXC.__init__(self, 'LDA')
Пример #21
0
class TB09Kernel:
    name = 'TB09'
    type = 'MGGA'
    alpha = -0.012
    beta = 1.023

    def __init__(self, c=None):
        self.tb09 = LibXC('MGGA_X_TB09').xc.tb09
        self.ldac = LibXC('LDA_C_PW')

        self.fixedc = c is not None  # calculate c or use fixed value
        self.c = c  # amount of "exact exchange"
        self.n = 0  # Lebedev quadrature point number (0-49)
        self.sign = 1.0  # sign of PAW correction: +1 for AE and -1 for PS
        self.I = None  # integral from Eq. (3)

    def calculate(self, e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg, tau_sg,
                  dedtau_sg):
        ns = len(n_sg)
        n_sg[n_sg < 1e-6] = 1e-6

        if n_sg.ndim == 4:
            if not self.fixedc:
                if self.c is None:
                    # We don't have the integral yet - just use 1.0:
                    self.c = 1.0
                else:
                    self.I = self.world.sum(self.I)
                    self.c = (self.alpha + self.beta *
                              (self.I / self.gd.volume)**0.5)

                # Start calculation of c for use in the next SCF step:
                if ns == 1:
                    gradn_g = sigma_xg[0]**0.5
                else:
                    gradn_g = (sigma_xg[0] + 2 * sigma_xg[1] +
                               sigma_xg[2])**0.5
                self.I = self.gd.integrate(gradn_g / n_sg.sum(0))
                # The domain is not distributed like the PAW corrections:
                self.I /= self.world.size

            lapl_sg = self.gd.empty(ns)
            for n_g, lapl_g in zip(n_sg, lapl_sg):
                self.lapl.apply(n_g, lapl_g)

        else:
            rgd = self.rgd
            lapl_sg = []
            for n_Lg in self.n_sLg:
                lapl_g = rgd.laplace(np.dot(self.Y_L, n_Lg))
                l = 0
                L1 = 0
                while L1 < len(self.Y_L):
                    L2 = L1 + 2 * l + 1
                    n_g = np.dot(self.Y_L[L1:L2], n_Lg[L1:L2])
                    with seterr(divide='ignore', invalid='ignore'):
                        lapl_g -= l * (l + 1) * n_g / rgd.r_g**2
                    lapl_g[0] = 0.0
                    L1 = L2
                    l += 1
                lapl_sg.append(lapl_g)

            if not self.fixedc:
                # PAW corrections to integral:
                w = self.sign * weight_n[self.n]
                if ns == 1:
                    gradn_g = sigma_xg[0]**0.5
                else:
                    gradn_g = (sigma_xg[0] + 2 * sigma_xg[1] +
                               sigma_xg[2])**0.5
                self.I += w * rgd.integrate(gradn_g / n_sg.sum(0))

                self.n += 1
                if self.n == len(weight_n):
                    self.n = 0
                    self.sign = -self.sign

        # dedn_sg[:] = 0.0
        sigma_xg[sigma_xg < 1e-10] = 1e-10
        tau_sg[tau_sg < 1e-10] = 1e-10

        for n_g, sigma_g, lapl_g, tau_g, v_g in zip(n_sg, sigma_xg[::2],
                                                    lapl_sg, tau_sg, dedn_sg):
            self.tb09(self.c, n_g.ravel(), sigma_g, lapl_g, tau_g, v_g,
                      dedsigma_xg)

        self.ldac.calculate(e_g, n_sg, dedn_sg)
        e_g[:] = 0.0

        dedsigma_xg[:] = 0.0
        dedtau_sg[:] = 0.0
Пример #22
0
def vdw_C09(*args, **kwargs):
    return VDWXC(semilocal_xc=GGA(LibXC('GGA_X_C09X+LDA_C_PW')),
                 name='vdW-C09',
                 libvdwxc_name='vdW-DF',
                 *args,
                 **kwargs)
Пример #23
0
def XC(kernel, parameters=None, atoms=None, collinear=True):
    """Create XCFunctional object.

    kernel: XCKernel object, dict or str
        Kernel object or name of functional.
    parameters: ndarray
        Parameters for BEE functional.

    Recognized names are: LDA, PW91, PBE, revPBE, RPBE, BLYP, HCTH407,
    TPSS, M06-L, revTPSS, vdW-DF, vdW-DF2, EXX, PBE0, B3LYP, BEE,
    GLLBSC.  One can also use equivalent libxc names, for example
    GGA_X_PBE+GGA_C_PBE is equivalent to PBE, and LDA_X to the LDA exchange.
    In this way one has access to all the functionals defined in libxc.
    See xc_funcs.h for the complete list.  """

    if isinstance(kernel, basestring):
        kernel = xc_string_to_dict(kernel)

    kwargs = {}
    if isinstance(kernel, dict):
        kwargs = kernel.copy()
        name = kwargs.pop('name')
        backend = kwargs.pop('backend', None)

        if backend == 'libvdwxc' or name == 'vdW-DF-cx':
            # Must handle libvdwxc before old vdw implementation to override
            # behaviour for 'name'.  Also, cx is not implemented by the old
            # vdW module, so that always refers to libvdwxc.
            from gpaw.xc.libvdwxc import get_libvdwxc_functional
            return get_libvdwxc_functional(name=name, **kwargs)
        elif backend:
            error_msg = "A special backend for the XC functional was given, "\
                "but not understood. Please check if there's a typo."
            raise ValueError(error_msg)

        if name in ['vdW-DF', 'vdW-DF2', 'optPBE-vdW', 'optB88-vdW',
                    'C09-vdW', 'mBEEF-vdW', 'BEEF-vdW']:
            from gpaw.xc.vdw import VDWFunctional
            return VDWFunctional(name, **kwargs)
        elif name in ['EXX', 'PBE0', 'B3LYP',
                      'CAMY-BLYP', 'CAMY-B3LYP', 'LCY-BLYP', 'LCY-PBE']:
            from gpaw.xc.hybrid import HybridXC
            return HybridXC(name, **kwargs)
        elif name.startswith('LCY-') or name.startswith('CAMY-'):
            parts = name.split('(')
            from gpaw.xc.hybrid import HybridXC
            return HybridXC(parts[0], omega=float(parts[1][:-1]))
        elif name in ['HSE03', 'HSE06']:
            from gpaw.xc.exx import EXX
            return EXX(name, **kwargs)
        elif name == 'BEE1':
            from gpaw.xc.bee import BEE1
            kernel = BEE1(parameters)
        elif name == 'BEE2':
            from gpaw.xc.bee import BEE2
            kernel = BEE2(parameters)
        elif name.startswith('GLLB'):
            from gpaw.xc.gllb.nonlocalfunctionalfactory import \
                NonLocalFunctionalFactory
            # Pass kwargs somewhere?
            xc = NonLocalFunctionalFactory().get_functional_by_name(name)
            xc.print_functional()
            return xc
        elif name == 'LB94':
            from gpaw.xc.lb94 import LB94
            kernel = LB94()
        elif name == 'TB09':
            from gpaw.xc.tb09 import TB09
            return TB09(**kwargs)
        elif name.endswith('PZ-SIC'):
            from gpaw.xc.sic import SIC
            return SIC(xc=name[:-7], **kwargs)
        elif name in ['TPSS', 'M06-L', 'M06L', 'revTPSS']:
            if name == 'M06L':
                name = 'M06-L'
                warnings.warn('Please use M06-L instead of M06L')
            from gpaw.xc.kernel import XCKernel
            kernel = XCKernel(name)
        elif name.startswith('old'):
            from gpaw.xc.kernel import XCKernel
            kernel = XCKernel(name[3:])
        elif name == 'PPLDA':
            from gpaw.xc.lda import PurePythonLDAKernel
            kernel = PurePythonLDAKernel()
        elif name in ['pyPBE', 'pyPBEsol', 'pyRPBE', 'pyzvPBEsol']:
            from gpaw.xc.gga import PurePythonGGAKernel
            kernel = PurePythonGGAKernel(name)
        elif name == '2D-MGGA':
            from gpaw.xc.mgga import PurePython2DMGGAKernel
            kernel = PurePython2DMGGAKernel(name, parameters)
        elif name[0].isdigit():
            from gpaw.xc.parametrizedxc import ParametrizedKernel
            kernel = ParametrizedKernel(name)
        elif name == 'null':
            from gpaw.xc.kernel import XCNull
            kernel = XCNull()
        elif name == 'QNA':
            from gpaw.xc.qna import QNA
            return QNA(atoms, kernel['parameters'], kernel['setup_name'],
                       alpha=kernel['alpha'], stencil=kwargs.get('stencil', 2))
        else:
            kernel = LibXC(name)

    if kernel.type == 'LDA':
        if not collinear:
            kernel = NonCollinearLDAKernel(kernel)
        xc = LDA(kernel, **kwargs)
        return xc

    elif kernel.type == 'GGA':
        return GGA(kernel, **kwargs)
    else:
        return MGGA(kernel, **kwargs)
Пример #24
0
    def __init__(self,
                 world=None,
                 Zab=-0.8491,
                 vdwcoef=1.0,
                 q0cut=5.0,
                 phi0=0.5,
                 ds=1.0,
                 Dmax=20.0,
                 nD=201,
                 ndelta=21,
                 soft_correction=False,
                 setup_name='revPBE',
                 verbose=False,
                 energy_only=False):
        """vdW-DF.

        parameters:

        name: str
            Name of functional.
        world: MPI communicator
            Communicator to parallelize over.  Defaults to gpaw.mpi.world.
        q0cut: float
            Maximum value for q0.
        phi0: float
            Smooth value for phi(0,0).
        ds: float
            Cutoff for smooth kernel.
        Dmax: float
            Maximum value for D.
        nD: int
            Number of values for D in kernel-table.
        ndelta: int
            Number of values for delta in kernel-table.
        soft_correction: bool
            Correct for soft kernel.
        kernel:
            Which kernel to use.
        Zab:
            parameter in nonlocal kernel.
        vdwcoef: float
            Scaling of vdW energy.
        verbose: bool
            Print useful information.
        """

        if world is None:
            self.world = mpi.world
        else:
            self.world = world

        self.Zab = Zab
        self.vdwcoef = vdwcoef
        self.q0cut = q0cut
        self.phi0 = phi0
        self.ds = ds

        self.delta_i = np.linspace(0, 1.0, ndelta)
        self.D_j = np.linspace(0, Dmax, nD)

        self.verbose = verbose

        self.read_table()

        self.soft_correction = soft_correction
        if soft_correction:
            dD = self.D_j[1]
            self.C_soft = np.dot(self.D_j**2, self.phi_ij[0]) * 4 * pi * dD

        self.gd = None
        self.energy_only = energy_only
        self.timer = nulltimer

        self.LDAc = LibXC('LDA_C_PW')
        self.setup_name = setup_name
Пример #25
0
def vdw_optB88(*args, **kwargs):
    return VDWXC(semilocal_xc=GGA(LibXC('GGA_X_OPTB88_VDW+LDA_C_PW')),
                 name='optB88',
                 libvdwxc_name='vdW-DF',
                 *args,
                 **kwargs)
Пример #26
0
class BEEVDWKernel(XCKernel):
    """Kernel for BEEVDW functionals."""
    def __init__(self, bee, xcoefs, ldac, ggac):
        """BEEVDW kernel.

        parameters:

        bee : str
            choose BEE1 or BEE2 exchange basis expansion.
        xcoefs : array
            coefficients for exchange.
        ldac : float
            coefficient for LDA correlation.
        pbec : float
            coefficient for PBE correlation.

        """

        if bee == 'BEE2':
            self.BEE = BEE2(xcoefs)
            self.GGAc = LibXC('GGA_C_PBE')
            self.xtype = 'GGA'
            self.type = 'GGA'
        elif bee == 'BEE3':
            self.BEE = LibXC('MGGA_X_MBEEFVDW')
            self.GGAc = LibXC('GGA_C_PBE_SOL')
            self.xtype = 'MGGA'
            self.type = 'MGGA'
        else:
            raise ValueError('Unknown BEE exchange: %s', bee)

        self.LDAc = LibXC('LDA_C_PW')
        self.ldac = ldac
        self.ggac = ggac
        if bee in ['BEE1', 'BEE2']:
            self.ggac -= 1.0
        self.name = 'BEEVDW'

    def calculate(self,
                  e_g,
                  n_sg,
                  dedn_sg,
                  sigma_xg=None,
                  dedsigma_xg=None,
                  tau_sg=None,
                  dedtau_sg=None):
        if debug:
            self.check_arguments(e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg,
                                 tau_sg, dedtau_sg)

        if self.xtype == 'GGA':
            self.BEE.calculate(e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg)
        elif self.xtype == 'MGGA':
            self.BEE.calculate(e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg,
                               tau_sg, dedtau_sg)
        else:
            raise ValueError('Unexpected value of xtype:', self.xtype)

        e0_g = np.empty_like(e_g)
        dedn0_sg = np.empty_like(dedn_sg)
        dedsigma0_xg = np.empty_like(dedsigma_xg)
        for coef, kernel in [(self.ldac, self.LDAc), (self.ggac, self.GGAc)]:
            dedn0_sg[:] = 0.0
            kernel.calculate(e0_g, n_sg, dedn0_sg, sigma_xg, dedsigma0_xg)
            e_g += coef * e0_g
            dedn_sg += coef * dedn0_sg
            if kernel.type == 'GGA':
                dedsigma_xg += coef * dedsigma0_xg
Пример #27
0
def XC(kernel, parameters=None):
    """Create XCFunctional object.

    kernel: XCKernel object or str
        Kernel object or name of functional.
    parameters: ndarray
        Parameters for BEE functional.

    Recognized names are: LDA, PW91, PBE, revPBE, RPBE, BLYP, HCTH407,
    TPSS, M06-L, revTPSS, vdW-DF, vdW-DF2, EXX, PBE0, B3LYP, BEE,
    GLLBSC.  One can also use equivalent libxc names, for example
    GGA_X_PBE+GGA_C_PBE is equivalent to PBE, and LDA_X to the LDA exchange.
    In this way one has access to all the functionals defined in libxc.
    See xc_funcs.h for the complete list.  """

    if isinstance(kernel, basestring):
        name = kernel
        if name in [
                'vdW-DF', 'vdW-DF2', 'optPBE-vdW', 'optB88-vdW', 'C09-vdW',
                'mBEEF-vdW', 'BEEF-vdW'
        ]:
            from gpaw.xc.vdw import VDWFunctional
            return VDWFunctional(name)
        elif name in ['EXX', 'PBE0', 'B3LYP']:
            from gpaw.xc.hybrid import HybridXC
            return HybridXC(name)
        elif name in ['HSE03', 'HSE06']:
            from gpaw.xc.exx import EXX
            return EXX(name)
        elif name == 'BEE1':
            from gpaw.xc.bee import BEE1
            kernel = BEE1(parameters)
        elif name == 'BEE2':
            from gpaw.xc.bee import BEE2
            kernel = BEE2(parameters)
        elif name.startswith('GLLB'):
            from gpaw.xc.gllb.nonlocalfunctionalfactory import \
                NonLocalFunctionalFactory
            xc = NonLocalFunctionalFactory().get_functional_by_name(name)
            xc.print_functional()
            return xc
        elif name == 'LB94':
            from gpaw.xc.lb94 import LB94
            kernel = LB94()
        elif name == 'TB09':
            from gpaw.xc.tb09 import TB09
            return TB09()
        elif name.startswith('ODD_'):
            from ODD import ODDFunctional
            return ODDFunctional(name[4:])
        elif name.endswith('PZ-SIC'):
            try:
                from ODD import PerdewZungerSIC as SIC
                return SIC(xc=name[:-7])
            except:
                from gpaw.xc.sic import SIC
                return SIC(xc=name[:-7])
        elif name in ['TPSS', 'M06-L', 'M06L', 'revTPSS']:
            if name == 'M06L':
                name = 'M06-L'
                warnings.warn('Please use M06-L instead of M06L')
            from gpaw.xc.kernel import XCKernel
            kernel = XCKernel(name)
        elif name.startswith('old'):
            from gpaw.xc.kernel import XCKernel
            kernel = XCKernel(name[3:])
        elif name == 'PPLDA':
            from gpaw.xc.lda import PurePythonLDAKernel
            kernel = PurePythonLDAKernel()
        elif name in ['pyPBE', 'pyPBEsol', 'pyRPBE', 'pyzvPBEsol']:
            from gpaw.xc.gga import PurePythonGGAKernel
            kernel = PurePythonGGAKernel(name)
        elif name == '2D-MGGA':
            from gpaw.xc.mgga import PurePython2DMGGAKernel
            kernel = PurePython2DMGGAKernel(name, parameters)
        elif name[0].isdigit():
            from gpaw.xc.parametrizedxc import ParametrizedKernel
            kernel = ParametrizedKernel(name)
        else:
            kernel = LibXC(kernel)
    if kernel.type == 'LDA':
        return LDA(kernel)
    elif kernel.type == 'GGA':
        return GGA(kernel)
    else:
        return MGGA(kernel)
Пример #28
0
class VDWFunctional(GGA):
    """Base class for vdW-DF."""

    def __init__(
        self,
        name,
        world=None,
        q0cut=5.0,
        phi0=0.5,
        ds=1.0,
        Dmax=20.0,
        nD=201,
        ndelta=21,
        soft_correction=False,
        kernel=None,
        Zab=None,
        vdwcoef=1.0,
        verbose=False,
        energy_only=False,
    ):
        """vdW-DF.

        parameters:

        name: str
            Name of functional.
        world: MPI communicator
            Communicator to parallelize over.  Defaults to gpaw.mpi.world.
        q0cut: float
            Maximum value for q0.
        phi0: float
            Smooth value for phi(0,0).
        ds: float
            Cutoff for smooth kernel.
        Dmax: float
            Maximum value for D.
        nD: int
            Number of values for D in kernel-table.
        ndelta: int
            Number of values for delta in kernel-table.
        soft_correction: bool
            Correct for soft kernel.
        kernel:
            Which kernel to use.
        Zab:
            parameter in nonlocal kernel.
        vdwcoef: float
            Scaling of vdW energy.
        verbose: bool
            Print useful information.
        """

        if world is None:
            self.world = mpi.world
        else:
            self.world = world

        self.q0cut = q0cut
        self.phi0 = phi0
        self.ds = ds

        self.delta_i = np.linspace(0, 1.0, ndelta)
        self.D_j = np.linspace(0, Dmax, nD)

        self.verbose = verbose

        self.read_table()

        self.soft_correction = soft_correction
        if soft_correction:
            dD = self.D_j[1]
            self.C_soft = np.dot(self.D_j ** 2, self.phi_ij[0]) * 4 * pi * dD

        self.gd = None
        self.energy_only = energy_only
        self.timer = nulltimer

        if name == "vdW-DF":
            assert kernel is None and Zab is None
            kernel = LibXC("GGA_X_PBE_R+LDA_C_PW")
            Zab = -0.8491
        elif name == "vdW-DF2":
            assert kernel is None and Zab is None
            kernel = LibXC("GGA_X_RPW86+LDA_C_PW")
            Zab = -1.887
        elif name == "optPBE-vdW":
            assert kernel is None and Zab is None
            kernel = LibXC("GGA_X_OPTPBE_VDW+LDA_C_PW")
            Zab = -0.8491
        elif name == "optB88-vdW":
            assert kernel is None and Zab is None
            kernel = LibXC("GGA_X_OPTB88_VDW+LDA_C_PW")
            Zab = -0.8491
        elif name == "C09-vdW":
            assert kernel is None and Zab is None
            kernel = LibXC("GGA_X_C09X+LDA_C_PW")
            Zab = -0.8491
        else:
            assert kernel is not None and Zab is not None

        self.Zab = Zab
        GGA.__init__(self, kernel)
        self.vdwcoef = vdwcoef
        self.name = name
        self.LDAc = LibXC("LDA_C_PW")

    def get_setup_name(self):
        return "revPBE"

    def initialize(self, density, hamiltonian, wfs, occupations):
        self.timer = wfs.timer

    def get_Ecnl(self):
        return self.Ecnl

    def calculate_gga(self, e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg):
        GGA.calculate_gga(self, e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg)

        eLDAc_g = self.gd.empty()
        vLDAc_sg = self.gd.zeros(1)

        if self.vdwcoef == 0.0:
            return

        if len(n_sg) == 1:
            self.LDAc.calculate(eLDAc_g, n_sg, vLDAc_sg)
            e = self.get_non_local_energy(n_sg[0], sigma_xg[0], eLDAc_g, vLDAc_sg[0], dedn_sg[0], dedsigma_xg[0])
        else:
            n_sg = n_sg.sum(0)
            n_sg.shape = (1,) + n_sg.shape
            self.LDAc.calculate(eLDAc_g, n_sg, vLDAc_sg)
            v_g = np.zeros_like(e_g)
            deda2nl_g = np.zeros_like(e_g)
            a2_g = sigma_xg[0] + 2 * sigma_xg[1] + sigma_xg[2]
            e = self.get_non_local_energy(n_sg[0], a2_g, eLDAc_g, vLDAc_sg[0], v_g, deda2nl_g)
            dedsigma_xg[0] += self.vdwcoef * deda2nl_g
            dedsigma_xg[1] += self.vdwcoef * 2 * deda2nl_g
            dedsigma_xg[2] += self.vdwcoef * deda2nl_g
            dedn_sg += self.vdwcoef * v_g

        if self.gd.comm.rank == 0:
            e_g[0, 0, 0] += self.vdwcoef * e / self.gd.dv

    def get_non_local_energy(self, n_g=None, a2_g=None, e_LDAc_g=None, v_LDAc_g=None, v_g=None, deda2_g=None):
        """Calculate non-local correlation energy.

        parameters:

        n_g: ndarray
            Density.
        a2_g: ndarray
            Absolute value of the gradient of the density - squared.
        e_LDAc_g: ndarray
            LDA correlation energy density.
        """

        gd = self.gd

        n_g = n_g.clip(1e-7, np.inf)

        # Calculate q0 and cut it off smoothly at q0cut:
        kF_g = (3 * pi ** 2 * n_g) ** (1.0 / 3.0)
        q0_g, dhdx_g = hRPS(kF_g - 4 * pi / 3 * e_LDAc_g / n_g - self.Zab / 36 / kF_g * a2_g / n_g ** 2, self.q0cut)

        if self.verbose:
            print ("VDW: q0 (min, mean, max): (%f, %f, %f)" % (q0_g.min(), q0_g.mean(), q0_g.max()))

        if self.soft_correction:
            dEcnl = gd.integrate(n_g ** 2 / q0_g ** 3) * 0.5 * self.C_soft
        else:
            dEcnl = 0.0

        # Distribute density and q0 to all processors:
        n_g = gd.collect(n_g, broadcast=True)
        q0_g = gd.collect(q0_g, broadcast=True)

        if not self.energy_only:
            self.dhdx_g = gd.collect(dhdx_g, broadcast=True)

        Ecnl = self.calculate_6d_integral(n_g, q0_g, a2_g, e_LDAc_g, v_LDAc_g, v_g, deda2_g)
        Ecnl += dEcnl
        self.Ecnl = Ecnl
        return Ecnl

    def read_table(self):
        name = "phi-%.3f-%.3f-%.3f-%d-%d.pckl" % (self.phi0, self.ds, self.D_j[-1], len(self.delta_i), len(self.D_j))

        if "GPAW_VDW" in os.environ:
            print "Use of GPAW_VDW is deprecated."
            print "Put", name, "in your GPAW_SETUP_PATH directory."
            dirs = [os.environ["GPAW_VDW"]]
        else:
            dirs = setup_paths + ["."]

        for dir in dirs:
            filename = os.path.join(dir, name)
            if os.path.isfile(filename):
                self.phi_ij = pickle.load(open(filename))
                if self.verbose:
                    print "VDW: using", filename
                return

        print "VDW: Could not find table file:", name
        self.make_table(name)

    def make_table(self, name):
        print "VDW: Generating vdW-DF kernel ..."
        print "VDW:",
        ndelta = len(self.delta_i)
        nD = len(self.D_j)
        self.phi_ij = np.zeros((ndelta, nD))
        for i in range(self.world.rank, ndelta, self.world.size):
            print ndelta - i,
            sys.stdout.flush()
            delta = self.delta_i[i]
            for j in range(nD - 1, -1, -1):
                D = self.D_j[j]
                d = D * (1.0 + delta)
                dp = D * (1.0 - delta)
                if d ** 2 + dp ** 2 > self.ds ** 2:
                    self.phi_ij[i, j] = phi(d, dp)
                else:
                    P = np.polyfit(
                        [0, self.D_j[j + 1] ** 2, self.D_j[j + 2] ** 2],
                        [self.phi0, self.phi_ij[i, j + 1], self.phi_ij[i, j + 2]],
                        2,
                    )
                    self.phi_ij[i, : j + 3] = np.polyval(P, self.D_j[: j + 3] ** 2)
                    break

        self.world.sum(self.phi_ij)

        print
        print "VDW: Done!"
        if self.world.rank == 0:
            pickle.dump(self.phi_ij, open(name, "w"), pickle.HIGHEST_PROTOCOL)

    def make_prl_plot(self, multiply_by_4_pi_D_squared=True):
        import pylab as plt

        x = np.linspace(0, 8.0, 100)
        for delta in [0, 0.5, 0.9]:
            y = [self.phi(D * (1.0 + delta), D * (1.0 - delta)) for D in x]
            if multiply_by_4_pi_D_squared:
                y *= 4 * pi * x ** 2
            plt.plot(x, y, label=r"$\delta=%.1f$" % delta)
        plt.legend(loc="best")
        plt.plot(x, np.zeros(len(x)), "k-")
        plt.xlabel("D")
        plt.ylabel(r"$4\pi D^2 \phi(\rm{Hartree})$")
        plt.show()

    def phi(self, d, dp):
        """Kernel function.

        Uses bi-linear interpolation and returns zero for D > Dmax.
        """

        P = self.phi_ij
        D = (d + dp) / 2.0
        if D < 1e-14:
            return P[0, 0]
        if D >= self.D_j[-1]:
            return 0.0

        delta = abs((d - dp) / (2 * D))
        ddelta = self.delta_i[1]
        x = delta / ddelta
        i = int(x)
        if i == len(self.delta_i) - 1:
            i -= 1
            x = 1.0
        else:
            x -= i

        dD = self.D_j[1]
        y = D / dD
        j = int(y)
        y -= j
        return x * (y * P[i + 1, j + 1] + (1 - y) * P[i + 1, j]) + (1 - x) * (y * P[i, j + 1] + (1 - y) * P[i, j])
Пример #29
0
from gpaw.xc.libxc import LibXC
from math import pi
import numpy as np

nspins = 1
for name in [
        'LDA',
        'PBE',
        'revPBE',
        'RPBE',
        'LDA_X',
        'GGA_X_PBE_R',
        'GGA_X_RPBE',
        'LDA_C_PW',
]:
    xc = LibXC(name)
    xc.initialize(nspins)
    libxc = xc.xc
    lxc_fxc = libxc.calculate_fxc_spinpaired
    lxc_fxc_fd = libxc.calculate_fxc_fd_spinpaired
    na = 2.0
    if nspins == 2:
        nb = 1.0
    else:
        nb = 0.0
    print na, nb
    if (nb > 0.0): assert (nspins == 2)
    if nspins == 2:
        sigma0 = 2.0  # (0.0, 1.0, 1.0)
        sigma1 = 2.0
        sigma2 = 5.0  # (1.0, 2.0, 0.0)
Пример #30
0
import numpy as np
from gpaw.xc.libxc import LibXC, short_names
from gpaw.xc.kernel import XCKernel, codes
from gpaw.xc.bee import BEE1

functionals = [LibXC(name) for name in short_names]
functionals += [XCKernel(name) for name in codes]
functionals += [BEE1()]
#name = 'LDA'
#name = 'PBE'
#functionals = [LibXC('MGGA_X_TPSS')]
#               XCKernel(name)]
#functionals = [f for f in functionals if f.type=='MGGA']

def f1(n_xg, xc):
    e_g = np.empty_like(n_xg[0])
    n_sg = n_xg[:1]
    sigma_xg = n_xg[1:2]
    tau_sg = n_xg[2:]
    dedn_sg = np.zeros_like(n_sg)
    dedsigma_xg = np.zeros_like(sigma_xg)
    dedtau_sg = np.zeros_like(tau_sg)
    xc.calculate(e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg, tau_sg, dedtau_sg)
    return e_g, np.concatenate((dedn_sg, dedsigma_xg, dedtau_sg))

def f2(n_xg, xc):
    e_g = np.empty_like(n_xg[0])
    n_sg = n_xg[:2]
    sigma_xg = n_xg[2:5]
    tau_sg = n_xg[5:]
    dedn_sg = np.zeros_like(n_sg)
Пример #31
0
from gpaw.xc.libxc import LibXC
from math import pi
import numpy as np

nspins = 1
for name in [
    'LDA', 'PBE', 'revPBE', 'RPBE',
    'LDA_X', 'GGA_X_PBE_R', 'GGA_X_RPBE',
    'LDA_C_PW',
    ]:
    xc = LibXC(name)
    xc.initialize(nspins)
    libxc = xc.xc
    lxc_fxc = libxc.calculate_fxc_spinpaired
    lxc_fxc_fd = libxc.calculate_fxc_fd_spinpaired
    na = 2.0
    if nspins == 2:
        nb = 1.0
    else:
        nb = 0.0
    print na, nb
    if (nb > 0.0): assert (nspins == 2)
    if nspins == 2:
        sigma0 = 2.0 # (0.0, 1.0, 1.0)
        sigma1 = 2.0
        sigma2 = 5.0 # (1.0, 2.0, 0.0)
    else:
        sigma0 = 2.0 # (0.0, 1.0, 1.0)
        sigma1 = 0.0
        sigma2 = 0.0
    taua=(3.*pi**2)**(2./3.)*na**(5./3.)/2.*sigma0
Пример #32
0
def vdw_df2(*args, **kwargs):
    return VDWXC(semilocal_xc=GGA(LibXC('GGA_X_RPW86+LDA_C_PW')),
                 name='vdW-DF2',
                 *args,
                 **kwargs)
Пример #33
0
import numpy as np
from gpaw.xc.libxc import LibXC, short_names
from gpaw.xc.kernel import XCKernel, codes
from gpaw.test import equal

funcs = []
modes = []
for name in short_names:
    try:
        LibXC(name)
    except NameError:
        continue
    funcs.append(name)
    modes.append(0)
for name in codes:
    funcs.append(name)
    modes.append(1)


def create_xc(func, mode):
    isinstance(func, str)
    isinstance(mode, int)
    if mode == 0:
        xc = LibXC(func)
    else:
        xc = XCKernel(func)
    return xc


def f1(n_xg, xc):
    e_g = np.empty_like(n_xg[0])
Пример #34
0
class VDWFunctionalBase:
    """Base class for vdW-DF."""
    def __init__(self,
                 world=None,
                 Zab=-0.8491,
                 vdwcoef=1.0,
                 q0cut=5.0,
                 phi0=0.5,
                 ds=1.0,
                 Dmax=20.0,
                 nD=201,
                 ndelta=21,
                 soft_correction=False,
                 setup_name='revPBE',
                 verbose=False,
                 energy_only=False):
        """vdW-DF.

        parameters:

        name: str
            Name of functional.
        world: MPI communicator
            Communicator to parallelize over.  Defaults to gpaw.mpi.world.
        q0cut: float
            Maximum value for q0.
        phi0: float
            Smooth value for phi(0,0).
        ds: float
            Cutoff for smooth kernel.
        Dmax: float
            Maximum value for D.
        nD: int
            Number of values for D in kernel-table.
        ndelta: int
            Number of values for delta in kernel-table.
        soft_correction: bool
            Correct for soft kernel.
        kernel:
            Which kernel to use.
        Zab:
            parameter in nonlocal kernel.
        vdwcoef: float
            Scaling of vdW energy.
        verbose: bool
            Print useful information.
        """

        if world is None:
            self.world = mpi.world
        else:
            self.world = world

        self.Zab = Zab
        self.vdwcoef = vdwcoef
        self.q0cut = q0cut
        self.phi0 = phi0
        self.ds = ds

        self.delta_i = np.linspace(0, 1.0, ndelta)
        self.D_j = np.linspace(0, Dmax, nD)

        self.verbose = verbose

        self.read_table()

        self.soft_correction = soft_correction
        if soft_correction:
            dD = self.D_j[1]
            self.C_soft = np.dot(self.D_j**2, self.phi_ij[0]) * 4 * pi * dD

        self.gd = None
        self.energy_only = energy_only
        self.timer = nulltimer

        self.LDAc = LibXC('LDA_C_PW')
        self.setup_name = setup_name

    def get_setup_name(self):
        return self.setup_name

    def get_Ecnl(self):
        return self.Ecnl

    def calculate_impl(self, gd, n_sg, v_sg, e_g):
        sigma_xg, dedsigma_xg, gradn_svg = gga_vars(gd, self.grad_v, n_sg)
        self.calculate_exchange(e_g, n_sg, v_sg, sigma_xg, dedsigma_xg)
        self.calculate_correlation(e_g, n_sg, v_sg, sigma_xg, dedsigma_xg)
        add_gradient_correction(self.grad_v, gradn_svg, sigma_xg, dedsigma_xg,
                                v_sg)

    def calculate_exchange(self, e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg):
        raise NotImplementedError

    def calculate_correlation(self, e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg):
        eLDAc_g = self.gd.empty()
        vLDAc_sg = self.gd.zeros(1)

        if self.vdwcoef == 0.0:
            return

        if len(n_sg) == 1:
            self.LDAc.calculate(eLDAc_g, n_sg, vLDAc_sg)
            e = self.get_non_local_energy(n_sg[0], sigma_xg[0], eLDAc_g,
                                          vLDAc_sg[0], dedn_sg[0],
                                          dedsigma_xg[0])
        else:
            n_sg = n_sg.sum(0)
            n_sg.shape = (1, ) + n_sg.shape
            self.LDAc.calculate(eLDAc_g, n_sg, vLDAc_sg)
            v_g = np.zeros_like(e_g)
            deda2nl_g = np.zeros_like(e_g)
            a2_g = sigma_xg[0] + 2 * sigma_xg[1] + sigma_xg[2]
            e = self.get_non_local_energy(n_sg[0], a2_g, eLDAc_g, vLDAc_sg[0],
                                          v_g, deda2nl_g)
            dedsigma_xg[0] += self.vdwcoef * deda2nl_g
            dedsigma_xg[1] += self.vdwcoef * 2 * deda2nl_g
            dedsigma_xg[2] += self.vdwcoef * deda2nl_g
            dedn_sg += self.vdwcoef * v_g

        if self.gd.comm.rank == 0:
            e_g[0, 0, 0] += self.vdwcoef * e / self.gd.dv

    def get_non_local_energy(self,
                             n_g=None,
                             a2_g=None,
                             e_LDAc_g=None,
                             v_LDAc_g=None,
                             v_g=None,
                             deda2_g=None):
        """Calculate non-local correlation energy.

        parameters:

        n_g: ndarray
            Density.
        a2_g: ndarray
            Absolute value of the gradient of the density - squared.
        e_LDAc_g: ndarray
            LDA correlation energy density.
        """

        gd = self.gd

        n_g = n_g.clip(1e-7, np.inf)

        # Calculate q0 and cut it off smoothly at q0cut:
        kF_g = (3 * pi**2 * n_g)**(1.0 / 3.0)
        q0_g, dhdx_g = hRPS(
            kF_g - 4 * pi / 3 * e_LDAc_g / n_g -
            self.Zab / 36 / kF_g * a2_g / n_g**2, self.q0cut)

        if self.verbose:
            print(('VDW: q0 (min, mean, max): (%f, %f, %f)' %
                   (q0_g.min(), q0_g.mean(), q0_g.max())))

        if self.soft_correction:
            dEcnl = -gd.integrate(n_g**2 / q0_g**3) * 0.5 * self.C_soft
        else:
            dEcnl = 0.0

        # Distribute density and q0 to all processors:
        n_g = gd.collect(n_g, broadcast=True)
        q0_g = gd.collect(q0_g, broadcast=True)

        if not self.energy_only:
            self.dhdx_g = gd.collect(dhdx_g, broadcast=True)

        Ecnl = self.calculate_6d_integral(n_g, q0_g, a2_g, e_LDAc_g, v_LDAc_g,
                                          v_g, deda2_g)
        Ecnl += dEcnl
        self.Ecnl = Ecnl
        return Ecnl

    def read_table(self):
        name = ('phi-%.3f-%.3f-%.3f-%d-%d.txt' %
                (self.phi0, self.ds, self.D_j[-1], len(
                    self.delta_i), len(self.D_j)))
        dirs = setup_paths + ['.']

        for dir in dirs:
            filename = os.path.join(dir, name)
            if os.path.isfile(filename):
                self.phi_ij = np.loadtxt(filename)
                if self.verbose:
                    print('VDW: using', filename)
                return

        if sys.version_info[0] == 2:
            oldname = name[:-3] + 'pckl'
            for dir in dirs:
                filename = os.path.join(dir, oldname)
                if os.path.isfile(filename):
                    self.phi_ij = pickle.load(open(filename, 'rb'))
                    if self.verbose:
                        print('VDW: using', filename)
                    return

        print('VDW: Could not find table file:', name)
        self.make_table(name)

    def make_table(self, name):
        print('VDW: Generating vdW-DF kernel ...')
        print('VDW:', end=' ')
        ndelta = len(self.delta_i)
        nD = len(self.D_j)
        self.phi_ij = np.zeros((ndelta, nD))
        for i in range(self.world.rank, ndelta, self.world.size):
            print(ndelta - i, end=' ')
            sys.stdout.flush()
            delta = self.delta_i[i]
            for j in range(nD - 1, -1, -1):
                D = self.D_j[j]
                d = D * (1.0 + delta)
                dp = D * (1.0 - delta)
                if d**2 + dp**2 > self.ds**2:
                    with seterr(divide='ignore'):
                        self.phi_ij[i, j] = phi(d, dp)
                else:
                    P = np.polyfit([0, self.D_j[j + 1]**2, self.D_j[j + 2]**2],
                                   [
                                       self.phi0, self.phi_ij[i, j + 1],
                                       self.phi_ij[i, j + 2]
                                   ], 2)
                    self.phi_ij[i, :j + 3] = np.polyval(P, self.D_j[:j + 3]**2)
                    break

        self.world.sum(self.phi_ij)

        print()
        print('VDW: Done!')
        header = ('phi0={0:.3f}, ds={1:.3f}, Dmax={2:.3f}, nD={3}, ndelta={4}'.
                  format(self.phi0, self.ds, self.D_j[-1], len(self.delta_i),
                         len(self.D_j)))
        if self.world.rank == 0:
            np.savetxt(name, self.phi_ij, header=header)

    def make_prl_plot(self, multiply_by_4_pi_D_squared=True):
        import pylab as plt
        x = np.linspace(0, 8.0, 100)
        for delta in [0, 0.5, 0.9]:
            y = [self.phi(D * (1.0 + delta), D * (1.0 - delta)) for D in x]
            if multiply_by_4_pi_D_squared:
                y *= 4 * pi * x**2
            plt.plot(x, y, label=r'$\delta=%.1f$' % delta)
        plt.legend(loc='best')
        plt.plot(x, np.zeros(len(x)), 'k-')
        plt.xlabel('D')
        plt.ylabel(r'$4\pi D^2 \phi(\rm{Hartree})$')
        plt.show()

    def phi(self, d, dp):
        """Kernel function.

        Uses bi-linear interpolation and returns zero for D > Dmax.
        """

        P = self.phi_ij
        D = (d + dp) / 2.0
        if D < 1e-14:
            return P[0, 0]
        if D >= self.D_j[-1]:
            return 0.0

        delta = abs((d - dp) / (2 * D))
        ddelta = self.delta_i[1]
        x = delta / ddelta
        i = int(x)
        if i == len(self.delta_i) - 1:
            i -= 1
            x = 1.0
        else:
            x -= i

        dD = self.D_j[1]
        y = D / dD
        j = int(y)
        y -= j
        return (x * (y * P[i + 1, j + 1] + (1 - y) * P[i + 1, j]) + (1 - x) *
                (y * P[i, j + 1] + (1 - y) * P[i, j]))
Пример #35
0
from math import pi
import numpy as np
from gpaw.xc.libxc import LibXC

x0 = LibXC('LDA_X')

def f0(xc, rs, s):
    n = 3 / (4 * pi * rs**3)
    third = 1.0 / 3.0
    kF = (3 * pi**2 * n)**third
    a2 = (2 * kF * n * s)**2
    e = np.zeros(1)
    xc.calculate(e,
                 np.array([[n]]), np.zeros((1, 1)),
                 np.array([[a2]]), np.zeros((1, 1)))
    exc = n * e[0]
    x0.calculate(e, np.array([[n]]), np.zeros((1, 1)))
    ex0 = n * e[0]
    return exc / ex0

def f1(xc, rs, s):
    n = 3 / (4 * pi * rs**3)
    # na = 2 * n
    third = 1.0 / 3.0
    kF = (3 * pi**2 * n)**third
    a2 = (2 * kF * n * s)**2
    e = np.zeros(1)
    xc.calculate(e,
                 np.array([[n], [0]]), np.zeros((2, 1)),
                 np.array([[a2], [0], [0]]), np.zeros((3, 1)))
    exc = n * e[0]
Пример #36
0
def vdw_df(*args, **kwargs):
    return VDWXC(semilocal_xc=GGA(LibXC('GGA_X_PBE_R+LDA_C_PW')),
                 name='vdW-DF',
                 *args,
                 **kwargs)
Пример #37
0
    def __init__(
        self,
        name,
        world=None,
        q0cut=5.0,
        phi0=0.5,
        ds=1.0,
        Dmax=20.0,
        nD=201,
        ndelta=21,
        soft_correction=False,
        kernel=None,
        Zab=None,
        vdwcoef=1.0,
        verbose=False,
        energy_only=False,
    ):
        """vdW-DF.

        parameters:

        name: str
            Name of functional.
        world: MPI communicator
            Communicator to parallelize over.  Defaults to gpaw.mpi.world.
        q0cut: float
            Maximum value for q0.
        phi0: float
            Smooth value for phi(0,0).
        ds: float
            Cutoff for smooth kernel.
        Dmax: float
            Maximum value for D.
        nD: int
            Number of values for D in kernel-table.
        ndelta: int
            Number of values for delta in kernel-table.
        soft_correction: bool
            Correct for soft kernel.
        kernel:
            Which kernel to use.
        Zab:
            parameter in nonlocal kernel.
        vdwcoef: float
            Scaling of vdW energy.
        verbose: bool
            Print useful information.
        """

        if world is None:
            self.world = mpi.world
        else:
            self.world = world

        self.q0cut = q0cut
        self.phi0 = phi0
        self.ds = ds

        self.delta_i = np.linspace(0, 1.0, ndelta)
        self.D_j = np.linspace(0, Dmax, nD)

        self.verbose = verbose

        self.read_table()

        self.soft_correction = soft_correction
        if soft_correction:
            dD = self.D_j[1]
            self.C_soft = np.dot(self.D_j ** 2, self.phi_ij[0]) * 4 * pi * dD

        self.gd = None
        self.energy_only = energy_only
        self.timer = nulltimer

        if name == "vdW-DF":
            assert kernel is None and Zab is None
            kernel = LibXC("GGA_X_PBE_R+LDA_C_PW")
            Zab = -0.8491
        elif name == "vdW-DF2":
            assert kernel is None and Zab is None
            kernel = LibXC("GGA_X_RPW86+LDA_C_PW")
            Zab = -1.887
        elif name == "optPBE-vdW":
            assert kernel is None and Zab is None
            kernel = LibXC("GGA_X_OPTPBE_VDW+LDA_C_PW")
            Zab = -0.8491
        elif name == "optB88-vdW":
            assert kernel is None and Zab is None
            kernel = LibXC("GGA_X_OPTB88_VDW+LDA_C_PW")
            Zab = -0.8491
        elif name == "C09-vdW":
            assert kernel is None and Zab is None
            kernel = LibXC("GGA_X_C09X+LDA_C_PW")
            Zab = -0.8491
        else:
            assert kernel is not None and Zab is not None

        self.Zab = Zab
        GGA.__init__(self, kernel)
        self.vdwcoef = vdwcoef
        self.name = name
        self.LDAc = LibXC("LDA_C_PW")
Пример #38
0
class BEEVDWKernel(XCKernel):
    """Kernel for BEEVDW functionals."""
    def __init__(self, bee, xcoefs, ldac, ggac):
        """BEEVDW kernel.

        parameters:

        bee : str
            choose BEE1 or BEE2 exchange basis expansion.
        xcoefs : array
            coefficients for exchange.
        ldac : float
            coefficient for LDA correlation.
        pbec : float
            coefficient for PBE correlation.

        """

        if bee == 'BEE2':
            self.BEE = BEE2(xcoefs)
            self.GGAc = LibXC('GGA_C_PBE')
            self.xtype = 'GGA'
            self.type = 'GGA'
        elif bee == 'BEE3':
            self.BEE = LibXC('MGGA_X_MBEEFVDW')
            self.GGAc = LibXC('GGA_C_PBE_SOL')
            self.xtype = 'MGGA'
            self.type = 'MGGA'
        else:
            raise ValueError('Unknown BEE exchange: %s', bee)

        self.LDAc = LibXC('LDA_C_PW')
        self.ldac = ldac
        self.ggac = ggac
        if bee in ['BEE1', 'BEE2']:
            self.ggac -= 1.0
        self.name = 'BEEVDW'

    def calculate(self, e_g, n_sg, dedn_sg,
                  sigma_xg=None, dedsigma_xg=None,
                  tau_sg=None, dedtau_sg=None):
        if debug:
            self.check_arguments(e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg,
                                 tau_sg, dedtau_sg)

        if self.xtype == 'GGA':
            self.BEE.calculate(e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg)
        elif self.xtype == 'MGGA':
            self.BEE.calculate(e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg,
                               tau_sg, dedtau_sg)
        else:
            raise ValueError('Unexpected value of xtype:', self.xtype)

        e0_g = np.empty_like(e_g)
        dedn0_sg = np.empty_like(dedn_sg)
        dedsigma0_xg = np.empty_like(dedsigma_xg)
        for coef, kernel in [(self.ldac, self.LDAc),
                             (self.ggac, self.GGAc)]:
            dedn0_sg[:] = 0.0
            kernel.calculate(e0_g, n_sg, dedn0_sg, sigma_xg, dedsigma0_xg)
            e_g += coef * e0_g
            dedn_sg += coef * dedn0_sg
            if kernel.type == 'GGA':
                dedsigma_xg += coef * dedsigma0_xg