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)
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)
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)
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)
def __init__(self, name, hybrid=None, xc=None, finegrid=False, alpha=None, skip_gamma=False, gygi=False, acdf=True, qsym=True, txt=None, ecut=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. 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.alpha = alpha self.qsym = qsym self.skip_gamma = skip_gamma self.gygi = gygi self.acdf = acdf self.exx = None self.ecut = ecut if txt is None: if rank == 0: #self.txt = devnull self.txt = sys.stdout else: sys.stdout = devnull self.txt = devnull else: assert type(txt) is str from ase.parallel import paropen self.txt = paropen(txt, 'w') XCFunctional.__init__(self, name)
a = 4.0 x = Atoms(cell=(a, a, a)) # no atoms class HarmonicPotential: def __init__(self, alpha): self.alpha = alpha self.vext_g = None def get_potential(self, gd): if self.vext_g is None: r_vg = gd.get_grid_point_coordinates() self.vext_g = self.alpha * ((r_vg - a / Bohr / 2)**2).sum(0) return self.vext_g calc = GPAW(charge=-8, nbands=4, h=0.2, xc=XC(XCNull()), external=HarmonicPotential(0.5), poissonsolver=NoInteractionPoissonSolver(), eigensolver='cg') x.calc = calc x.get_potential_energy() eigs = calc.get_eigenvalues() equal(eigs[0], 1.5 * Hartree, 0.002) equal(abs(eigs[1:] - 2.5 * Hartree).max(), 0, 0.003)
def __init__(self, calc, xc=None, kpts=None, bands=None, ecut=None, omega=None, world=mpi.world, txt=sys.stdout, timer=None): PairDensity.__init__(self, calc, ecut, world=world, txt=txt, timer=timer) if xc is None or xc == 'EXX': self.exx_fraction = 1.0 xc = XC(XCNull()) elif xc == 'PBE0': self.exx_fraction = 0.25 xc = XC('HYB_GGA_XC_PBEH') elif xc == 'HSE03': omega = 0.106 self.exx_fraction = 0.25 xc = XC('HYB_GGA_XC_HSE03') elif xc == 'HSE06': omega = 0.11 self.exx_fraction = 0.25 xc = XC('HYB_GGA_XC_HSE06') elif xc == 'B3LYP': self.exx_fraction = 0.2 xc = XC('HYB_GGA_XC_B3LYP') self.xc = xc self.omega = omega self.exc = np.nan # density dependent part of xc-energy self.kpts = select_kpts(kpts, self.calc) if bands is None: # Do all occupied bands: bands = [0, self.nocc2] prnt('Calculating exact exchange contributions for band index', '%d-%d' % (bands[0], bands[1] - 1), file=self.fd) prnt('for IBZ k-points with indices:', ', '.join(str(i) for i in self.kpts), file=self.fd) self.bands = bands if self.ecut is None: self.ecut = self.calc.wfs.pd.ecut prnt('Plane-wave cutoff: %.3f eV' % (self.ecut * Hartree), file=self.fd) shape = (self.calc.wfs.nspins, len(self.kpts), bands[1] - bands[0]) self.exxvv_sin = np.zeros(shape) # valence-valence exchange energies self.exxvc_sin = np.zeros(shape) # valence-core exchange energies self.f_sin = np.empty(shape) # occupation numbers # The total EXX energy will not be calculated if we are only # interested in a few eigenvalues for a few k-points self.exx = np.nan # total EXX energy self.exxvv = np.nan # valence-valence self.exxvc = np.nan # valence-core self.exxcc = 0.0 # core-core self.mysKn1n2 = None # my (s, K, n1, n2) indices self.distribute_k_points_and_bands(0, self.nocc2) # All occupied states: self.mykpts = [ self.get_k_point(s, K, n1, n2) for s, K, n1, n2 in self.mysKn1n2 ] prnt('Using Wigner-Seitz truncated coulomb interaction.', file=self.fd) self.wstc = WignerSeitzTruncatedCoulomb(self.calc.wfs.gd.cell_cv, self.calc.wfs.kd.N_c, self.fd) self.iG_qG = {} # cache # PAW matrices: self.V_asii = [] # valence-valence correction self.C_aii = [] # valence-core correction self.initialize_paw_exx_corrections()
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)