Beispiel #1
0
    def __init__(self, name, hybrid=None, xc=None, finegrid=False):
        """Mix standard functionals with exact exchange.

        name: str
            Name of hybrid functional.
        hybrid: float
            Fraction of exact exchange.
        xc: str or XCFunctional object
            Standard DFT functional with scaled down exchange.
        finegrid: boolean
            Use fine grid for energy functional evaluations?
        """

        if name == 'EXX':
            assert hybrid is None and xc is None
            hybrid = 1.0
            xc = XC(XCNull())
        elif name == 'PBE0':
            assert hybrid is None and xc is None
            hybrid = 0.25
            xc = XC('HYB_GGA_XC_PBEH')
        elif name == 'B3LYP':
            assert hybrid is None and xc is None
            hybrid = 0.2
            xc = XC('HYB_GGA_XC_B3LYP')
            
        if isinstance(xc, str):
            xc = XC(xc)

        self.hybrid = hybrid
        self.xc = xc
        self.type = xc.type
        self.finegrid = finegrid

        XCFunctional.__init__(self, name)
Beispiel #2
0
    def forced_update(self):
        """Recalc yourself."""
        if not self.force_ApmB:
            Om = OmegaMatrix
            name = 'LrTDDFT'
            if self.xc:
                xc = XC(self.xc)
                if hasattr(xc, 'hybrid') and xc.hybrid > 0.0:
                    Om = ApmB
                    name = 'LrTDDFThyb'
        else:
            Om = ApmB
            name = 'LrTDDFThyb'

        self.kss = KSSingles(calculator=self.calculator,
                             nspins=self.nspins,
                             eps=self.eps,
                             istart=self.istart,
                             jend=self.jend,
                             energy_range=self.energy_range,
                             txt=self.txt)

        self.Om = Om(self.calculator, self.kss,
                     self.xc, self.derivative_level, self.numscale,
                     finegrid=self.finegrid, eh_comm=self.eh_comm,
                     txt=self.txt)
        self.name = name
Beispiel #3
0
    def initialize(self):
        self.occupations = self.nlfunc.occupations
        self.xc = XC(self.functional)

        # Always 1 spin, no matter what calculation nspins is
        self.vt_sg = self.nlfunc.finegd.empty(1)
        self.e_g = self.nlfunc.finegd.empty()  #.ravel()
Beispiel #4
0
def create_setup(symbol, xc='LDA', lmax=0,
                 type='paw', basis=None, setupdata=None,
                 filter=None, world=None):
    if isinstance(xc, str):
        xc = XC(xc)

    if isinstance(type, str) and ':' in type:
        # Parse DFT+U parameters from type-string:
        # Examples: "type:l,U" or "type:l,U,scale"
        type, lu = type.split(':')
        if type == '':
            type = 'paw'
        l = 'spdf'.find(lu[0])
        assert lu[1] == ','
        U = lu[2:]
        if ',' in U:
            U, scale = U.split(',')
        else:
            scale = True
        U = float(U) / units.Hartree
        scale = int(scale)
    else:
        U = None

    if setupdata is None:
        if type == 'hgh' or type == 'hgh.sc':
            lmax = 0
            from gpaw.hgh import HGHSetupData, setups, sc_setups
            if type == 'hgh.sc':
                table = sc_setups
            else:
                table = setups
            parameters = table[symbol]
            setupdata = HGHSetupData(parameters)
        elif type == 'ah':
            from gpaw.ah import AppelbaumHamann
            ah = AppelbaumHamann()
            ah.build(basis)
            return ah
        elif type == 'ae':
            from gpaw.ae import HydrogenAllElectronSetup
            assert symbol == 'H'
            ae = HydrogenAllElectronSetup()
            ae.build(basis)
            return ae
        elif type == 'ghost':
            from gpaw.lcao.bsse import GhostSetupData
            setupdata = GhostSetupData(symbol)
        else:
            setupdata = SetupData(symbol, xc.get_setup_name(),
                                  type, True,
                                  world=world)
    if hasattr(setupdata, 'build'):
        setup = LeanSetup(setupdata.build(xc, lmax, basis, filter))
        if U is not None:
            setup.set_hubbard_u(U, l, scale)
        return setup
    else:
        return setupdata
Beispiel #5
0
 def get_xc_difference(self, xc):
     if isinstance(xc, str):
         xc = XC(xc)
     xc.initialize(self.density, self.hamiltonian, self.wfs,
                   self.occupations)
     xc.set_positions(self.atoms.get_scaled_positions() % 1.0)
     if xc.orbital_dependent:
         self.converge_wave_functions()
     return self.hamiltonian.get_xc_difference(xc, self.density) * Hartree
Beispiel #6
0
    def __init__(self,
                 symbol,
                 xc='LDA',
                 spinpol=False,
                 dirac=False,
                 log=sys.stdout):
        """All-electron calculation for spherically symmetric atom.

        symbol: str (or int)
            Chemical symbol (or atomic number).
        xc: str
            Name of XC-functional.
        spinpol: bool
            If true, do spin-polarized calculation.  Default is spin-paired.
        dirac: bool
            Solve Dirac equation instead of Schrödinger equation.
        log: stream
            Text output."""

        if isinstance(symbol, int):
            symbol = chemical_symbols[symbol]
        self.symbol = symbol
        self.Z = atomic_numbers[symbol]

        self.nspins = 1 + int(bool(spinpol))

        self.dirac = bool(dirac)

        if isinstance(xc, str):
            self.xc = XC(xc)
        else:
            self.xc = xc

        if log is None:
            log = devnull
        self.fd = log

        self.vr_sg = None  # potential * r
        self.n_sg = 0.0  # density
        self.gd = None  # radial grid descriptor

        # Energies:
        self.ekin = None
        self.eeig = None
        self.eH = None
        self.eZ = None

        self.channels = None

        self.initialize_configuration()

        self.log('Z:              ', self.Z)
        self.log('Name:           ', atomic_names[self.Z])
        self.log('Symbol:         ', symbol)
        self.log('XC-functional:  ', self.xc.name)
        self.log('Equation:       ', ['Schrödinger', 'Dirac'][self.dirac])
Beispiel #7
0
    def update(self,
               calculator=None,
               nspins=None,
               eps=0.001,
               istart=0,
               jend=None,
               energy_range=None,
               xc=None,
               derivative_level=None,
               numscale=0.001):

        changed = False
        if self.calculator != calculator or \
           self.nspins != nspins or \
           self.eps != eps or \
           self.istart != istart or \
           self.jend != jend :
            changed = True

        if not changed: return

        self.calculator = calculator
        self.nspins = nspins
        self.eps = eps
        self.istart = istart
        self.jend = jend
        self.xc = xc
        self.derivative_level = derivative_level
        self.numscale = numscale
        self.kss = KSSingles(calculator=calculator,
                             nspins=nspins,
                             eps=eps,
                             istart=istart,
                             jend=jend,
                             energy_range=energy_range,
                             txt=self.txt)
        if not self.force_ApmB:
            Om = OmegaMatrix
            name = 'LrTDDFT'
            if self.xc:
                xc = XC(self.xc)
                if hasattr(xc, 'hybrid') and xc.hybrid > 0.0:
                    Om = ApmB
                    name = 'LrTDDFThyb'
        else:
            Om = ApmB
            name = 'LrTDDFThyb'
        self.Om = Om(self.calculator,
                     self.kss,
                     self.xc,
                     self.derivative_level,
                     self.numscale,
                     finegrid=self.finegrid,
                     eh_comm=self.eh_comm,
                     txt=self.txt)
        self.name = name
Beispiel #8
0
 def get_xc_difference(self, xc):
     if isinstance(xc, (str, dict)):
         xc = XC(xc)
     xc.set_grid_descriptor(self.density.finegd)
     xc.initialize(self.density, self.hamiltonian, self.wfs,
                   self.occupations)
     xc.set_positions(self.spos_ac)
     if xc.orbital_dependent:
         self.converge_wave_functions()
     return self.hamiltonian.get_xc_difference(xc, self.density) * Ha
Beispiel #9
0
 def get_non_xc_total_energies(self):
     """Compile non-XC total energy contributions"""
     if self.e_dft is None:
         self.e_dft = self.calc.get_potential_energy()
     if self.e0 is None:
         from gpaw.xc.kernel import XCNull
         xc_null = XC(XCNull())
         self.e0 = self.e_dft + self.calc.get_xc_difference(xc_null)
     assert isinstance(self.e_dft, float)
     assert isinstance(self.e0, float)
Beispiel #10
0
    def _calculate_fxc(self, gd, n_sG):
        if self.functional == 'ALDA_x':
            n_G = np.sum(n_sG, axis=0)
            fx_G = -1. / 3. * (3. / np.pi)**(1. / 3.) * n_G**(-2. / 3.)
            return fx_G
        else:
            fxc_sG = np.zeros_like(n_sG)
            xc = XC(self.functional[1:])
            xc.calculate_fxc(gd, n_sG, fxc_sG)

            return fxc_sG[0]
Beispiel #11
0
    def linearize_to_xc(self, newxc):
        """Linearize Hamiltonian to difference XC functional.

        Used in real time TDDFT to perform calculations with various kernels.
        """
        if isinstance(newxc, str):
            newxc = XC(newxc)
        self.log('Linearizing xc-hamiltonian to ' + str(newxc))
        newxc.initialize(self.density, self.hamiltonian, self.wfs,
                         self.occupations)
        self.hamiltonian.linearize_to_xc(newxc, self.density)
Beispiel #12
0
    def propagate_single(self, dt):
        # --------------
        # Predictor step
        # --------------
        # 1. Calculate H(t)
        self.save_wfs()  # kpt.C2_nM = kpt.C_nM
        # 2. H_MM(t) = <M|H(t)|H>
        #    Solve Psi(t+dt) from (S_MM - 0.5j*H_MM(t)*dt) Psi(t+dt) =
        #                              (S_MM + 0.5j*H_MM(t)*dt) Psi(t)

        for k, kpt in enumerate(self.wfs.kpt_u):
            if self.fxc is not None:
                if self.time == 0.0:
                    kpt.deltaXC_H_MM = self.get_hamiltonian(kpt)
                    self.hamiltonian.xc = XC(self.fxc)
                    self.update_hamiltonian()
                    assert len(self.wfs.kpt_u) == 1
                    kpt.deltaXC_H_MM -= self.get_hamiltonian(kpt)

        self.update_hamiltonian()

        # Call registered callback functions
        self.call_observers(self.niter)

        for k, kpt in enumerate(self.wfs.kpt_u):
            kpt.H0_MM = self.get_hamiltonian(kpt)
            if self.fxc is not None:
                kpt.H0_MM += kpt.deltaXC_H_MM
            self.propagate_wfs(kpt.C_nM, kpt.C_nM, kpt.S_MM, kpt.H0_MM, dt)
        # ---------------
        # Propagator step
        # ---------------
        # 1. Calculate H(t+dt)
        self.update_hamiltonian()
        # 2. Estimate H(t+0.5*dt) ~ H(t) + H(t+dT)
        for k, kpt in enumerate(self.wfs.kpt_u):
            kpt.H0_MM *= 0.5
            if self.fxc is not None:
                #  Store this to H0_MM and maybe save one extra H_MM of
                # memory?
                kpt.H0_MM += 0.5 * (self.get_hamiltonian(kpt) +
                                    kpt.deltaXC_H_MM)
            else:
                #  Store this to H0_MM and maybe save one extra H_MM of
                # memory?
                kpt.H0_MM += 0.5 * self.get_hamiltonian(kpt)

            # 3. Solve Psi(t+dt) from
            # (S_MM - 0.5j*H_MM(t+0.5*dt)*dt) Psi(t+dt)
            #    = (S_MM + 0.5j*H_MM(t+0.5*dt)*dt) Psi(t)
            self.propagate_wfs(kpt.C2_nM, kpt.C_nM, kpt.S_MM, kpt.H0_MM, dt)
        self.niter += 1
        self.time += dt
Beispiel #13
0
    def get_density(self, atom_indices=None, gridrefinement=2):
        """Get sum of atomic densities from the given atom list.

        All atoms are taken if the list is not given."""

        all_atoms = self.calculator.get_atoms()
        if atom_indices is None:
            atom_indices = range(len(all_atoms))

        density = self.calculator.density
        spos_ac = all_atoms.get_scaled_positions()
        rank_a = self.finegd.get_ranks_from_positions(spos_ac)

        density.set_positions(all_atoms.get_scaled_positions(),
                              AtomPartition(self.finegd.comm, rank_a))

        # select atoms
        atoms = []
        D_asp = {}
        rank_a = []
        all_D_asp = self.calculator.density.D_asp
        all_rank_a = self.calculator.density.atom_partition.rank_a
        for a in atom_indices:
            if a in all_D_asp:
                D_asp[len(atoms)] = all_D_asp.get(a)
            atoms.append(all_atoms[a])
            rank_a.append(all_rank_a[a])
        atoms = Atoms(atoms,
                      cell=all_atoms.get_cell(),
                      pbc=all_atoms.get_pbc())
        spos_ac = atoms.get_scaled_positions()
        Z_a = atoms.get_atomic_numbers()

        par = self.calculator.parameters
        setups = Setups(Z_a, par.setups, par.basis, XC(par.xc),
                        self.calculator.wfs.world)

        # initialize
        self.initialize(setups, self.calculator.timer, np.zeros(len(atoms)),
                        False)
        self.set_mixer(None)

        # FIXME nparray causes partitionong.py test to fail
        self.set_positions(spos_ac, AtomPartition(self.gd.comm, rank_a))
        self.D_asp = D_asp
        basis_functions = BasisFunctions(
            self.gd, [setup.phit_j for setup in self.setups], cut=True)
        basis_functions.set_positions(spos_ac)
        self.initialize_from_atomic_densities(basis_functions)

        aed_sg, gd = self.get_all_electron_density(atoms, gridrefinement)
        return aed_sg.sum(axis=0), gd
Beispiel #14
0
    def beefvdw_energy_contribs_x(self):
        """Legendre polynomial exchange contributions to BEEF-vdW Etot"""
        self.get_non_xc_total_energies()
        e_pbe = (self.e_dft + self.calc.get_xc_difference('GGA_C_PBE') -
                 self.e0)

        exch = np.zeros(30)
        for p in range(30):
            pars = [4, 0, p, 1.0]
            bee = XC('BEE2', pars)
            exch[p] = (self.e_dft + self.calc.get_xc_difference(bee) -
                       self.e0 - e_pbe)
            del bee
        return exch
Beispiel #15
0
 def mbeef_exchange_energy_contribs(self):
     """Legendre polynomial exchange contributions to mBEEF Etot"""
     self.get_non_xc_total_energies()
     e_x = np.zeros((self.max_order, self.max_order))
     for p1 in range(self.max_order):  # alpha
         for p2 in range(self.max_order):  # s2
             pars_i = np.array([1, self.trans[0], p2, 1.0])
             pars_j = np.array([1, self.trans[1], p1, 1.0])
             pars = np.hstack((pars_i, pars_j))
             x = XC('2D-MGGA', pars)
             e_x[p1, p2] = (self.e_dft + self.calc.get_xc_difference(x) -
                            self.e0)
             del x
     return e_x
Beispiel #16
0
    def __init__(self, xc='LDA', finegrid=False, **parameters):
        """Self-Interaction Corrected Functionals (PZ-SIC).

        finegrid: boolean
            Use fine grid for energy functional evaluations?
        """

        if isinstance(xc, str):
            xc = XC(xc)
        self.xc = xc
        self.type = xc.type
        XCFunctional.__init__(self, xc.name + '-PZ-SIC')
        self.finegrid = finegrid
        self.parameters = parameters
Beispiel #17
0
    def _calculate_pol_fxc(self, gd, n_sG, m_G):
        """ Calculate polarized fxc """

        assert np.shape(m_G) == np.shape(n_sG[0])

        if self.functional == 'ALDA_x':
            fx_G = - (6. / np.pi)**(1. / 3.) \
                * (n_sG[0]**(1. / 3.) - n_sG[1]**(1. / 3.)) / m_G
            return fx_G
        else:
            v_sG = np.zeros(np.shape(n_sG))
            xc = XC(self.functional[1:])
            xc.calculate(gd, n_sG, v_sg=v_sG)

            return (v_sG[0] - v_sG[1]) / m_G
Beispiel #18
0
    def get_density(self, atom_indicees=None):
        """Get sum of atomic densities from the given atom list.

        All atoms are taken if the list is not given."""

        all_atoms = self.calculator.get_atoms()
        if atom_indicees is None:
            atom_indicees = range(len(all_atoms))

        density = self.calculator.density
        density.set_positions(all_atoms.get_scaled_positions() % 1.0,
                              self.calculator.wfs.rank_a)

        # select atoms
        atoms = []
        D_asp = {}
        rank_a = []
        all_D_asp = self.calculator.density.D_asp
        all_rank_a = self.calculator.density.rank_a
        for a in atom_indicees:
            if a in all_D_asp:
                D_asp[len(atoms)] = all_D_asp.get(a)
            atoms.append(all_atoms[a])
            rank_a.append(all_rank_a[a])
        atoms = Atoms(atoms, cell=all_atoms.get_cell())
        spos_ac = atoms.get_scaled_positions() % 1.0
        Z_a = atoms.get_atomic_numbers()

        par = self.calculator.input_parameters
        setups = Setups(Z_a, par.setups, par.basis, par.lmax, XC(par.xc),
                        self.calculator.wfs.world)
        self.D_asp = D_asp

        # initialize
        self.initialize(setups, par.stencils[1], self.calculator.timer,
                        [0] * len(atoms), False)
        self.set_mixer(None)
        self.set_positions(spos_ac, rank_a)
        basis_functions = BasisFunctions(
            self.gd, [setup.phit_j for setup in self.setups], cut=True)
        basis_functions.set_positions(spos_ac)
        self.initialize_from_atomic_densities(basis_functions)

        aed_sg, gd = Density.get_all_electron_density(self,
                                                      atoms,
                                                      gridrefinement=2)

        return aed_sg[0], gd
Beispiel #19
0
def paired():
    xc = XC('vdW-DF')
    n = 0.3 * np.ones((1, N, N, N))
    n += 0.01 * np.cos(np.arange(N) * 2 * pi / N)
    v = 0.0 * n
    xc.calculate(gd, n, v)
    n2 = 1.0 * n
    i = 1
    n2[0, i, i, i] += 0.00002
    x = v[0, i, i, i] * gd.dv
    E2 = xc.calculate(gd, n2, v)
    n2[0, i, i, i] -= 0.00004
    E2 -= xc.calculate(gd, n2, v)
    x2 = E2 / 0.00004
    print(i, x, x2, x - x2, x / x2)
    equal(x, x2, 2e-11)
Beispiel #20
0
    def __init__(self, xc='LDA', finegrid=False, **parameters):
        """Self-Interaction Corrected Functionals (PZ-SIC).

        finegrid: boolean
            Use fine grid for energy functional evaluations?
        """

        if isinstance(xc, basestring):
            xc = XC(xc)

        if xc.orbital_dependent:
            raise ValueError('SIC does not support ' + xc.name)

        self.xc = xc
        XCFunctional.__init__(self, xc.name + '-PZ-SIC', xc.type)
        self.finegrid = finegrid
        self.parameters = parameters
Beispiel #21
0
def polarized():
    xc = XC('vdW-DF')
    n = 0.04 * np.ones((2, N, N, N))
    n[1] = 0.3
    n[0] += 0.02 * np.sin(np.arange(N) * 2 * pi / N)
    n[1] += 0.2 * np.cos(np.arange(N) * 2 * pi / N)
    v = 0.0 * n
    xc.calculate(gd, n, v)
    n2 = 1.0 * n
    i = 1
    n2[0, i, i, i] += 0.00002
    x = v[0, i, i, i] * gd.dv
    E2 = xc.calculate(gd, n2, v)
    n2[0, i, i, i] -= 0.00004
    E2 -= xc.calculate(gd, n2, v)
    x2 = E2 / 0.00004
    print(i, x, x2, x - x2, x / x2)
    equal(x, x2, 1e-10)
Beispiel #22
0
    def get_density(self, atom_indices=None, gridrefinement=2):
        """Get sum of atomic densities from the given atom list.

        Parameters
        ----------
        atom_indices : list_like
            All atoms are taken if the list is not given.
        gridrefinement : 1, 2, 4
            Gridrefinement given to get_all_electron_density

        Returns
        -------
        type
             spin summed density, grid_descriptor
        """

        all_atoms = self.calculator.get_atoms()
        if atom_indices is None:
            atom_indices = range(len(all_atoms))

        # select atoms
        atoms = self.calculator.get_atoms()[atom_indices]
        spos_ac = atoms.get_scaled_positions()
        Z_a = atoms.get_atomic_numbers()

        par = self.calculator.parameters
        setups = Setups(Z_a, par.setups, par.basis, XC(par.xc),
                        self.calculator.wfs.world)

        # initialize
        self.initialize(setups, self.calculator.timer, np.zeros(
            (len(atoms), 3)), False)
        self.set_mixer(None)
        rank_a = self.gd.get_ranks_from_positions(spos_ac)
        self.set_positions(spos_ac, AtomPartition(self.gd.comm, rank_a))
        basis_functions = BasisFunctions(
            self.gd, [setup.phit_j for setup in self.setups], cut=True)
        basis_functions.set_positions(spos_ac)
        self.initialize_from_atomic_densities(basis_functions)

        aed_sg, gd = self.get_all_electron_density(atoms, gridrefinement)
        return aed_sg.sum(axis=0), gd
Beispiel #23
0
def get_radial_potential(calc, a, ai):
    """Calculates dV/dr / r for the effective potential.
    Below, f_g denotes dV/dr = minus the radial force"""

    rgd = a.xc_correction.rgd
    r_g = rgd.r_g
    r_g[0] = 1.0e-12
    dr_g = rgd.dr_g
    Ns = calc.wfs.nspins

    D_sp = calc.density.D_asp[ai]
    B_pq = a.xc_correction.B_pqL[:, :, 0]
    n_qg = a.xc_correction.n_qg
    D_sq = np.dot(D_sp, B_pq)
    n_sg = np.dot(D_sq, n_qg) / (4 * np.pi)**0.5
    n_sg[:] += a.xc_correction.nc_g / Ns

    # Coulomb force from nucleus
    fc_g = a.Z / r_g**2

    # Hartree force
    rho_g = 4 * np.pi * r_g**2 * dr_g * np.sum(n_sg, axis=0)
    fh_g = -np.array([np.sum(rho_g[:ig]) for ig in range(len(r_g))]) / r_g**2

    # xc force
    xc = XC(calc.get_xc_functional())
    v_sg = np.zeros_like(n_sg)
    xc.calculate_spherical(a.xc_correction.rgd, n_sg, v_sg)
    fxc_sg = np.array([a.xc_correction.rgd.derivative(v_sg[s])
                       for s in range(Ns)])
    fxc_g = np.sum(fxc_sg, axis=0) / Ns

    # f_sg = np.tile(fc_g, (Ns, 1)) + np.tile(fh_g, (Ns, 1)) + fxc_sg
    f_sg = np.tile(fc_g + fh_g + fxc_g, (Ns, 1))

    return f_sg[:] / r_g
Beispiel #24
0
def get_libvdwxc_functional(name, **kwargs):
    if 'name' in kwargs:
        name2 = kwargs.pop('name')
        assert name == name2
    funcs = {
        'vdW-DF': vdw_df,
        'vdW-DF2': vdw_df2,
        'vdW-DF-cx': vdw_df_cx,
        'optPBE-vdW': vdw_optPBE,
        'optB88-vdW': vdw_optB88,
        'C09-vdW': vdw_C09,
        'BEEF-vdW': vdw_beef,
        'mBEEF-vdW': vdw_mbeef
    }

    semilocal_xc = kwargs.pop('semilocal_xc', None)
    if semilocal_xc is not None:
        from gpaw.xc import XC
        semilocal_xc = XC(semilocal_xc)

    func = funcs[name](**kwargs)
    if semilocal_xc is not None:
        assert semilocal_xc.name == func.semilocal_xc.name
    return func
Beispiel #25
0
    def initialize_fxc(self, niter):
        self.has_fxc = self.fxc_name is not None
        if not self.has_fxc:
            return
        self.timer.start('Initialize fxc')
        # XXX: Similar functionality is available in
        # paw.py: PAW.linearize_to_xc(self, newxc)
        # See test/lcaotddft/fxc_vs_linearize.py

        get_H_MM = self.get_hamiltonian_matrix

        # Calculate deltaXC: 1. take current H_MM
        if niter == 0:
            self.deltaXC_H_uMM = [None] * len(self.wfs.kpt_u)
            for u, kpt in enumerate(self.wfs.kpt_u):
                self.deltaXC_H_uMM[u] = get_H_MM(kpt, addfxc=False)

        # Update hamiltonian.xc
        if self.fxc_name == 'RPA':
            xc_name = 'null'
        else:
            xc_name = self.fxc_name
        # XXX: xc is not written to the gpw file
        # XXX: so we need to set it always
        xc = XC(xc_name)
        xc.initialize(self.density, self.hamiltonian, self.wfs,
                      self.occupations)
        xc.set_positions(self.hamiltonian.spos_ac)
        self.hamiltonian.xc = xc
        self.update()

        # Calculate deltaXC: 2. update with new H_MM
        if niter == 0:
            for u, kpt in enumerate(self.wfs.kpt_u):
                self.deltaXC_H_uMM[u] -= get_H_MM(kpt, addfxc=False)
        self.timer.stop('Initialize fxc')
Beispiel #26
0
    def __init__(self, name, hybrid=None, xc=None, omega=None):
        """Mix standard functionals with exact exchange.

        name: str
            Name of hybrid functional.
        hybrid: float
            Fraction of exact exchange.
        xc: str or XCFunctional object
            Standard DFT functional with scaled down exchange.
        """

        if name == 'EXX':
            assert hybrid is None and xc is None
            hybrid = 1.0
            xc = XC(XCNull())
        elif name == 'PBE0':
            assert hybrid is None and xc is None
            hybrid = 0.25
            xc = XC('HYB_GGA_XC_PBEH')
        elif name == 'B3LYP':
            assert hybrid is None and xc is None
            hybrid = 0.2
            xc = XC('HYB_GGA_XC_B3LYP')
        elif name == 'HSE03':
            assert hybrid is None and xc is None and omega is None
            hybrid = 0.25
            omega = 0.106
            xc = XC('HYB_GGA_XC_HSE03')
        elif name == 'HSE06':
            assert hybrid is None and xc is None and omega is None
            hybrid = 0.25
            omega = 0.11
            xc = XC('HYB_GGA_XC_HSE06')

        if isinstance(xc, str):
            xc = XC(xc)

        self.hybrid = float(hybrid)
        self.xc = xc
        self.omega = omega
        self.type = xc.type

        XCFunctional.__init__(self, name)
Beispiel #27
0
    def __init__(self, symbol, xc='LDA', spinpol=False, dirac=False,
                 configuration=None,
                 log=None):
        """All-electron calculation for spherically symmetric atom.

        symbol: str (or int)
            Chemical symbol (or atomic number).
        xc: str
            Name of XC-functional.
        spinpol: bool
            If true, do spin-polarized calculation.  Default is spin-paired.
        dirac: bool
            Solve Dirac equation instead of Schrödinger equation.
        configuration: list
            Electronic configuration for symbol, format as in
            gpaw.atom.configurations
        log: stream
            Text output."""

        if isinstance(symbol, int):
            symbol = chemical_symbols[symbol]
        self.symbol = symbol
        self.Z = atomic_numbers[symbol]

        self.nspins = 1 + int(bool(spinpol))

        self.dirac = bool(dirac)

        if configuration is not None:
            self.configuration = copy.deepcopy(configuration)
        else:
            self.configuration = None

        self.scalar_relativistic = False

        if isinstance(xc, str):
            self.xc = XC(xc)
        else:
            self.xc = xc

        self.fd = log or sys.stdout

        self.vr_sg = None  # potential * r
        self.n_sg = 0.0  # density
        self.rgd = None  # radial grid descriptor

        # Energies:
        self.ekin = None
        self.eeig = None
        self.eH = None
        self.eZ = None

        self.channels = None

        self.initialize_configuration(self.configuration)

        self.log('Z:              ', self.Z)
        self.log('Name:           ', atomic_names[self.Z])
        self.log('Symbol:         ', symbol)
        self.log('XC-functional:  ', self.xc.name)
        self.log('Equation:       ', ['Schrödinger', 'Dirac'][self.dirac])

        self.method = 'Gaussian basis-set'
Beispiel #28
0
# -------------------------------------------------------------------

from gpaw.test.ut_common import ase_svnversion, shapeopt, TestCase, \
    TextTestRunner, CustomTextTestRunner, defaultTestLoader, \
    initialTestLoader, create_random_atoms, create_parsize_maxbands

memstats = False
if memstats:
    # Developer use of this feature requires ASE 3.1.0 svn.rev. 905 or later.
    assert ase_svnversion >= 905  # wasn't bug-free untill 973!
    from ase.utils.memory import MemorySingleton, MemoryStatistics

# -------------------------------------------------------------------

p = InputParameters(spinpol=False)
xc = XC(p.xc)
p.setups = dict([(symbol, SetupData(symbol, xc.name)) for symbol in 'HO'])


class UTBandParallelSetup(TestCase):
    """
    Setup a simple band parallel calculation."""

    # Number of bands
    nbands = 36

    # Spin-paired, single kpoint
    nspins = 1
    nibzkpts = 1

    # Strided or blocked groups
Beispiel #29
0
    def __init__(self, name, stencil=2, hybrid=None, xc=None, omega=None):
        """Mix standard functionals with exact exchange.

        name: str
            Name of hybrid functional.
        hybrid: float
            Fraction of exact exchange.
        xc: str or XCFunctional object
            Standard DFT functional with scaled down exchange.
        """

        rsf_functionals = {  # Parameters can also be taken from libxc
            'CAMY-BLYP': {  # Akinaga, Ten-no CPL 462 (2008) 348-351
                'alpha': 0.2,
                'beta': 0.8,
                'omega': 0.44,
                'cam': True,
                'rsf': 'Yukawa',
                'xc': 'HYB_GGA_XC_CAMY_BLYP'
            },
            'CAMY-B3LYP': {  # Seth, Ziegler JCTC 8 (2012) 901-907
                'alpha': 0.19,
                'beta': 0.46,
                'omega': 0.34,
                'cam': True,
                'rsf': 'Yukawa',
                'xc': 'HYB_GGA_XC_CAMY_B3LYP'
            },
            'LCY-BLYP': {  # Seth, Ziegler JCTC 8 (2012) 901-907
                'alpha': 0.0,
                'beta': 1.0,
                'omega': 0.75,
                'cam': False,
                'rsf': 'Yukawa',
                'xc': 'HYB_GGA_XC_LCY_BLYP'
            },
            'LCY-PBE': {  # Seth, Ziegler JCTC 8 (2012) 901-907
                'alpha': 0.0,
                'beta': 1.0,
                'omega': 0.75,
                'cam': False,
                'rsf': 'Yukawa',
                'xc': 'HYB_GGA_XC_LCY_PBE'
            }
        }
        self.omega = None
        self.cam_alpha = None
        self.cam_beta = None
        self.is_cam = False
        self.rsf = None

        def _xc(name):
            return {'name': name, 'stencil': stencil}

        if name == 'EXX':
            hybrid = 1.0
            xc = XC(XCNull())
        elif name == 'PBE0':
            hybrid = 0.25
            xc = XC(_xc('HYB_GGA_XC_PBEH'))
        elif name == 'B3LYP':
            hybrid = 0.2
            xc = XC(_xc('HYB_GGA_XC_B3LYP'))
        elif name == 'HSE03':
            hybrid = 0.25
            omega = 0.106
            xc = XC(_xc('HYB_GGA_XC_HSE03'))
        elif name == 'HSE06':
            hybrid = 0.25
            omega = 0.11
            xc = XC(_xc('HYB_GGA_XC_HSE06'))
        elif name in rsf_functionals:
            rsf_functional = rsf_functionals[name]
            self.cam_alpha = rsf_functional['alpha']
            self.cam_beta = rsf_functional['beta']
            self.omega = rsf_functional['omega']
            self.is_cam = rsf_functional['cam']
            self.rsf = rsf_functional['rsf']
            xc = XC(rsf_functional['xc'])
            hybrid = self.cam_alpha + self.cam_beta

        if isinstance(xc, (basestring, dict)):
            xc = XC(xc)

        self.hybrid = float(hybrid)
        self.xc = xc
        if omega is not None:
            omega = float(omega)
            if self.omega is not None and self.omega != omega:
                self.xc.kernel.set_omega(omega)
                # Needed to tune omega for RSF
            self.omega = omega
        XCFunctional.__init__(self, name, xc.type)
Beispiel #30
0
    E = xc.calculate(gd, n_sg, v_sg)
    print('E', E)

    dn = 1e-6

    all_indices = itertools.product(range(2), range(1, actual_n[0], 2),
                                    range(0, actual_n[1], 2),
                                    range(0, actual_n[2], 2))

    for testindex in all_indices:
        n1_sg = n_sg.copy()
        n2_sg = n_sg.copy()
        v = v_sg[testindex] * gd.dv
        n1_sg[testindex] -= dn
        n2_sg[testindex] += dn

        E1 = xc.calculate(gd, n1_sg, v_sg.copy())
        E2 = xc.calculate(gd, n2_sg, v_sg.copy())

        dedn = 0.5 * (E2 - E1) / dn
        err = abs(dedn - v)
        print('{}{} v={} fd={} err={}'.format(xc.name, list(testindex), v,
                                              dedn, err))
        assert err < tol, err


test(XC('PBE'))
test(vdw_df_cx())
test(vdw_df_cx(vdwcoef=0.0))
test(vdw_df_cx(vdwcoef=1e5), tol=2e-6)