예제 #1
0
import numpy as np
from ase import Atoms
from gpaw import GPAW
from gpaw.xc.sic import SIC
from gpaw.test import equal

a = 7.0
atom = Atoms('N', magmoms=[3], cell=(a, a, a))
molecule = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.14)], cell=(a, a, a))
atom.center()
molecule.center()

calc = GPAW(xc=SIC(), txt='n2.sic.new3b.txt', setups='hgh')

atom.set_calculator(calc)
e1 = atom.get_potential_energy()

molecule.set_calculator(calc)
e2 = molecule.get_potential_energy()
F_ac = molecule.get_forces()
print 2 * e1 - e2
print F_ac
예제 #2
0
    def calculate(self):
        ESIC = 0
        xc = self.paw.hamiltonian.xc
        assert xc.type == 'LDA'

        # Calculate the contribution from the core orbitals
        for a in self.paw.density.D_asp:
            setup = self.paw.density.setups[a]
            # TODO: Use XC which has been used to calculate the actual
            # calculation.
            # TODO: Loop over setups, not atoms.
            print('Atom core SIC for ', setup.symbol)
            print('%10s%10s%10s' % ('E_xc[n_i]', 'E_Ha[n_i]', 'E_SIC'))
            g = Generator(setup.symbol, xcname='LDA', nofiles=True, txt=None)
            g.run(**parameters[setup.symbol])
            njcore = g.njcore
            for f, l, e, u in zip(g.f_j[:njcore], g.l_j[:njcore],
                                  g.e_j[:njcore], g.u_j[:njcore]):
                # Calculate orbital density
                # NOTE: It's spherically symmetrized!
                #n = np.dot(self.f_j,
                assert l == 0, ('Not tested for l>0 core states')
                na = np.where(abs(u) < 1e-160, 0, u)**2 / (4 * pi)
                na[1:] /= g.r[1:]**2
                na[0] = na[1]
                nb = np.zeros(g.N)
                v_sg = np.zeros((2, g.N))
                e_g = np.zeros(g.N)
                vHr = np.zeros(g.N)
                Exc = xc.calculate_spherical(g.rgd, np.array([na, nb]), v_sg)
                hartree(0, na * g.r * g.dr, g.r, vHr)
                EHa = 2 * pi * np.dot(vHr * na * g.r, g.dr)
                print(
                    ('%10.2f%10.2f%10.2f' % (Exc * Hartree, EHa * Hartree, -f *
                                             (EHa + Exc) * Hartree)))
                ESIC += -f * (EHa + Exc)

        sic = SIC(finegrid=True, coulomb_factor=1, xc_factor=1)
        sic.initialize(self.paw.density, self.paw.hamiltonian, self.paw.wfs)
        sic.set_positions(self.paw.atoms.get_scaled_positions())

        print('Valence electron sic ')
        print('%10s%10s%10s%10s%10s%10s' %
              ('spin', 'k-point', 'band', 'E_xc[n_i]', 'E_Ha[n_i]', 'E_SIC'))
        assert len(
            self.paw.wfs.kpt_u) == 1, ('Not tested for bulk calculations')

        for s, spin in sic.spin_s.items():
            spin.initialize_orbitals()
            spin.update_optimal_states()
            spin.update_potentials()

            n = 0
            for xc, c in zip(spin.exc_m, spin.ecoulomb_m):
                print(('%10i%10i%10i%10.2f%10.2f%10.2f' %
                       (s, 0, n, -xc * Hartree, -c * Hartree, 2 *
                        (xc + c) * Hartree)))
                n += 1

            ESIC += spin.esic

        print('Total correction for self-interaction energy:')
        print('%10.2f eV' % (ESIC * Hartree))
        print('New total energy:')
        total = (ESIC * Hartree + self.paw.get_potential_energy() +
                 self.paw.get_reference_energy())
        print('%10.2f eV' % total)
        return total
예제 #3
0
    def calculate(self):
        ESIC = 0
        xc = self.paw.hamiltonian.xc
        assert xc.type == 'LDA'

        # Calculate the contribution from the core orbitals
        for a in self.paw.density.D_asp:
            setup = self.paw.density.setups[a]
            # TODO: Use XC which has been used to calculate the actual
            # calculation.
            # TODO: Loop over setups, not atoms.
            print('Atom core SIC for ', setup.symbol)
            print('%10s%10s%10s' %  ('E_xc[n_i]', 'E_Ha[n_i]', 'E_SIC'))
            g = Generator(setup.symbol, xcname='LDA', nofiles=True, txt=None)
            g.run(**parameters[setup.symbol])
            njcore = g.njcore
            for f, l, e, u in zip(g.f_j[:njcore], g.l_j[:njcore],
                                  g.e_j[:njcore], g.u_j[:njcore]):
                # Calculate orbital density
                # NOTE: It's spherically symmetrized!
                #n = np.dot(self.f_j,
                assert l == 0, ('Not tested for l>0 core states')
                na = np.where(abs(u) < 1e-160, 0,u)**2 / (4 * pi)
                na[1:] /= g.r[1:]**2
                na[0] = na[1]
                nb = np.zeros(g.N)
                v_sg = np.zeros((2, g.N)) 
                e_g = np.zeros(g.N)
                vHr = np.zeros(g.N)
                Exc = xc.calculate_spherical(g.rgd, np.array([na, nb]), v_sg)
                hartree(0, na * g.r * g.dr, g.r, vHr)
                EHa = 2*pi*np.dot(vHr*na*g.r , g.dr)
                print(('%10.2f%10.2f%10.2f' % (Exc * Hartree, EHa * Hartree,
                                               -f*(EHa+Exc) * Hartree)))
                ESIC += -f*(EHa+Exc)
                
        sic = SIC(finegrid=True, coulomb_factor=1, xc_factor=1)
        sic.initialize(self.paw.density, self.paw.hamiltonian, self.paw.wfs)
        sic.set_positions(self.paw.atoms.get_scaled_positions())
        
        print('Valence electron sic ')
        print('%10s%10s%10s%10s%10s%10s' % ('spin', 'k-point', 'band',
                                            'E_xc[n_i]', 'E_Ha[n_i]', 'E_SIC'))
        assert len(self.paw.wfs.kpt_u)==1, ('Not tested for bulk calculations')
        
        for s, spin in sic.spin_s.items():
            spin.initialize_orbitals()
            spin.update_optimal_states()
            spin.update_potentials()

            n = 0
            for xc, c in zip(spin.exc_m, spin.ecoulomb_m):
                print(('%10i%10i%10i%10.2f%10.2f%10.2f' %
                       (s, 0, n, -xc * Hartree, -c * Hartree,
                        2 * (xc + c) * Hartree)))
                n += 1

            ESIC += spin.esic
            
        print('Total correction for self-interaction energy:')
        print('%10.2f eV' % (ESIC * Hartree))
        print('New total energy:')
        total = (ESIC * Hartree + self.paw.get_potential_energy() +
                 self.paw.get_reference_energy())
        print('%10.2f eV' % total)
        return total
예제 #4
0
from __future__ import print_function

from ase import Atoms
from gpaw import GPAW
from gpaw.xc.sic import SIC

a = 7.0
atom = Atoms('N', magmoms=[3], cell=(a, a, a))
molecule = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.14)], cell=(a, a, a))
atom.center()
molecule.center()

calc = GPAW(xc=SIC(),
            eigensolver='rmm-diis',
            h=0.17,
            txt='n2.sic.new3b.txt',
            setups='hgh')

atom.set_calculator(calc)
e1 = atom.get_potential_energy()

molecule.set_calculator(calc)
e2 = molecule.get_potential_energy()
F_ac = molecule.get_forces()
print(2 * e1 - e2)
print(F_ac)
예제 #5
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)