Beispiel #1
0
    def __init__(self, width, orbitals):
        FermiDirac.__init__(self, width)
        self.orbitals = orbitals
        self.norbitals = len(self.orbitals)

        self.cnoe = 0.0
        for orb in self.orbitals:
            self.cnoe += orb[0]
Beispiel #2
0
    def __init__(self, width, orbitals):
        FermiDirac.__init__(self, width)
        self.orbitals = orbitals
        self.norbitals = len(self.orbitals)

        self.cnoe = 0.0
        for orb in self.orbitals:
            self.cnoe += orb[0]
Beispiel #3
0
 def calculate_band_energy(self, wfs):
     FermiDirac.calculate_band_energy(self, wfs)
     
     de_band = 0.0
     for kpt in wfs.kpt_u:
         if hasattr(kpt, 'c_on'):
             for ne, c_n in zip(kpt.ne_o, kpt.c_on):
                 de_band += ne * np.dot(np.abs(c_n)**2, kpt.eps_n)
     self.e_band += wfs.band_comm.sum(wfs.kpt_comm.sum(de_band))
Beispiel #4
0
    def calculate_band_energy(self, wfs):
        FermiDirac.calculate_band_energy(self, wfs)

        de_band = 0.0
        for kpt in wfs.kpt_u:
            if hasattr(kpt, 'c_on'):
                for ne, c_n in zip(kpt.ne_o, kpt.c_on):
                    de_band += ne * np.dot(np.abs(c_n)**2, kpt.eps_n)
        self.e_band += wfs.bd.comm.sum(wfs.kd.comm.sum(de_band))
Beispiel #5
0
def get_paw():
    """Return calculator object."""
    c = {'energy': 0.001, 'eigenstates': 0.001, 'density': 0.001}
    return GPAW(convergence=c, eigensolver=RMMDIIS(),
                xc='LCY-PBE:omega=0.83:unocc=True',
                parallel={'domain': world.size}, h=0.35,
                occupations=FermiDirac(width=0.0, fixmagmom=True))
Beispiel #6
0
def get_paw():
    """Return calculator object."""
    c = {'energy': 0.05, 'eigenstates': 0.05, 'density': 0.05}
    return GPAW(convergence=c, eigensolver=RMMDIIS(),
                nbands=3,
                xc='PBE',
#                experimental={'niter_fixdensity': 2},
                parallel={'domain': world.size}, h=0.35,
                occupations=FermiDirac(width=0.0, fixmagmom=True))
Beispiel #7
0
 def setup_calculator(self):
     hund = (len(self.system) == 1)
     self.system.set_calculator(
         GPAW(xc=self.xc,
              h=self.h,
              hund=hund,
              setups=self.setups,
              txt=self.name + '.txt',
              mode=self.mode,
              spinpol=True,
              occupations=FermiDirac(0, fixmagmom=True)))
Beispiel #8
0
    def calculate(self, wfs):
        FermiDirac.calculate(self, wfs)
        
        # Get the expansion coefficients c_un for each dscf-orbital
        # and incorporate their respective occupations into kpt.ne_o
        c_oun = []
        for orb in self.orbitals:
            ef = self.fermilevel
            if self.fixmagmom:
                fermilevels = [ef + 0.5 * self.split, ef - 0.5 * self.split]
            else:
                fermilevels = ef
            c_oun.append(orb[1].expand(fermilevels, wfs))

        for u, kpt in enumerate(wfs.kpt_u):
            kpt.ne_o = np.zeros(self.norbitals, dtype=float)
            kpt.c_on = np.zeros((self.norbitals, len(kpt.f_n)), dtype=complex)

            for o, orb in enumerate(self.orbitals):
                #TODO XXX false if orb[0]<0 since abs(c_n)**2>0
                #kpt.c_on[o,:] = abs(orb[0])**0.5 * c_oun[o][u]

                kpt.ne_o[o] = orb[0]
                kpt.c_on[o,:] = c_oun[o][u]

                if wfs.nspins == 2:
                    assert orb[2] in range(2), 'Invalid spin index'

                    if orb[2] == kpt.s:
                        kpt.ne_o[o] *= kpt.weight
                    else:
                        kpt.ne_o[o] = 0.0
                else:
                    kpt.ne_o[o] *= 0.5 * kpt.weight

        # Correct the magnetic moment
        for orb in self.orbitals:
            if orb[2] == 0:
                self.magmom += orb[0]
            elif orb[2] == 1:
                self.magmom -= orb[0]
Beispiel #9
0
    def calculate(self, wfs):
        FermiDirac.calculate(self, wfs)

        # Get the expansion coefficients c_un for each dscf-orbital
        # and incorporate their respective occupations into kpt.ne_o
        c_oun = []
        for orb in self.orbitals:
            ef = self.fermilevel
            if self.fixmagmom:
                fermilevels = [ef + 0.5 * self.split, ef - 0.5 * self.split]
            else:
                fermilevels = ef
            c_oun.append(orb[1].expand(fermilevels, wfs, self.fixmagmom))

        for u, kpt in enumerate(wfs.kpt_u):
            kpt.ne_o = np.zeros(self.norbitals, dtype=float)
            kpt.c_on = np.zeros((self.norbitals, len(kpt.f_n)), dtype=complex)

            for o, orb in enumerate(self.orbitals):
                # TODO XXX false if orb[0]<0 since abs(c_n)**2>0
                #kpt.c_on[o,:] = abs(orb[0])**0.5 * c_oun[o][u]

                kpt.ne_o[o] = orb[0]
                kpt.c_on[o, :] = c_oun[o][u]

                if wfs.nspins == 2:
                    assert orb[2] in range(2), 'Invalid spin index'

                    if orb[2] == kpt.s:
                        kpt.ne_o[o] *= kpt.weight
                    else:
                        kpt.ne_o[o] = 0.0
                else:
                    kpt.ne_o[o] *= 0.5 * kpt.weight

        # Correct the magnetic moment
        for orb in self.orbitals:
            if orb[2] == 0:
                self.magmom += orb[0]
            elif orb[2] == 1:
                self.magmom -= orb[0]
def efield(efield=0.05, n=30):
    printit('running GS calculation for {}'.format(efield))
    fname = "sb_relaxed.cif"
    a = read(fname)
    atom = read(fname)
    wire = make_supercell(atom, [[n, 0, 0], [0, 1, 0], [
                          0, 0, 1]], wrap=True, tol=1e-05)
    wire.center(vacuum=15, axis=0)
    a = wire.copy()
    if not os.path.isfile('gs_{}.gpw'.format(efield)):
        calc = GPAW(  # mode='lcao',
            mode='fd',
            basis='szp(dzp)',
            # eigensolver='cg',
            #mixer=Mixer(beta=0.2, nmaxold=3, weight=70.0),
            xc='PBE',
            # poissonsolver=DipoleCorrection(PoissonSolver(relax='GS'), 2),
            mixer=Mixer(beta=0.06, nmaxold=5, weight=100.0),
            occupations=FermiDirac(width=0.1),
            kpts={'density': 4.5},
            txt='gs_output_{}.txt'.format(efield),
            h=0.20,
            external=ConstantElectricField(efield, [0, 0, 1]))

        a.set_calculator(calc)
        a.get_potential_energy()
        calc.write('gs_{}.gpw'.format(efield))

    calc = GPAW('gs_{}.gpw'.format(efield),
                nbands=-100,
                fixdensity=True,
                symmetry='off',
                kpts={'path': 'XGX', 'npoints': 100},
                convergence={'bands': 'CBM+1'},
                txt='gs_output_{}.txt'.format(efield))
    calc.get_potential_energy()
    bs = calc.band_structure()
    bs.plot(filename='bandstructure_{}.png'.format(
        efield), show=False, emax=calc.get_fermi_level()+1, emin=calc.get_fermi_level()-1)
    bs.write('bs_{}.json'.format(
        efield))
    try:
        gap, p1, p2 = get_gap(calc)
        printit("{} {} {} {}".format(efield, gap, p1, p2), fname="gaps.dat")
    except:
        None
Beispiel #11
0
def do_gs_calc(fname):
    printit('running GS calculation')
    a = read(fname)

    calc = GPAW(mode='lcao',
                basis='dzp',
                xc='PBE',
                occupations=FermiDirac(width=0.01),
                kpts={
                    'size': (1, 20, 1),
                    'gamma': True
                },
                txt='gs_output.txt')

    a.set_calculator(calc)
    a.get_potential_energy()
    calc.write('gs_' + fname + '.gpw', mode='all')
    printit('GS calculation done')
Beispiel #12
0
def set_calculator(calc, e_km, v_knm=None, width=None):
    from gpaw.occupations import FermiDirac
    from ase.units import Hartree

    if width is None:
        width = calc.occupations.width * Hartree
    calc.wfs.bd.nbands *= 2
    calc.wfs.nspins = 1
    for kpt in calc.wfs.kpt_u:
        kpt.eps_n = e_km[kpt.k] / Hartree
        kpt.f_n = np.zeros_like(kpt.eps_n)
        kpt.weight /= 2
    ef = calc.occupations.fermilevel
    calc.occupations = FermiDirac(width)
    calc.occupations.nvalence = calc.wfs.setups.nvalence - calc.density.charge
    calc.occupations.fermilevel = ef
    calc.occupations.calculate_occupation_numbers(calc.wfs)
    for kpt in calc.wfs.kpt_u:
        kpt.f_n *= 2
        kpt.weight *= 2
def calculate(element, h, vacuum, xc, magmom):

    atom = Atoms([Atom(element, (0, 0, 0))])
    if magmom > 0.0:
        mms = [magmom for i in range(len(atom))]
        atom.set_initial_magnetic_moments(mms)

    atom.center(vacuum=vacuum)

    mixer = MixerSum(beta=0.2)
    if element == 'O':
        mixer = MixerSum(nmaxold=1, weight=100)
        atom.set_positions(atom.get_positions() + [0.0, 0.0, 0.0001])

    calc_atom = GPAW(h=h,
                     xc=data[element][xc][2],
                     occupations=FermiDirac(0.0, fixmagmom=True),
                     mixer=mixer,
                     nbands=-2,
                     txt='%s.%s.txt' % (element, xc))
    atom.set_calculator(calc_atom)

    mixer = Mixer(beta=0.2, weight=100)
    compound = molecule(element + '2')
    if compound == 'O2':
        mixer = MixerSum(beta=0.2)
        mms = [1.0 for i in range(len(compound))]
        compound.set_initial_magnetic_moments(mms)

    calc = GPAW(h=h,
                xc=data[element][xc][2],
                mixer=mixer,
                txt='%s2.%s.txt' % (element, xc))
    compound.set_distance(0, 1, data[element]['R_AA_B3LYP'])
    compound.center(vacuum=vacuum)

    compound.set_calculator(calc)

    if data[element][xc][3] == 'hyb_gga':  # only for hybrids
        e_atom = atom.get_potential_energy()
        e_compound = compound.get_potential_energy()

        calc_atom.set(xc=xc)
        calc.set(xc=xc)

    if 0:
        qn = QuasiNewton(compound)
        qn.attach(
            PickleTrajectory(element + '2' + '_' + xc + '.traj', 'w',
                             compound).write)
        qn.run(fmax=0.02)
    e_atom = atom.get_potential_energy()
    e_compound = compound.get_potential_energy()

    dHf_0 = (e_compound - 2 * e_atom + data[element]['ZPE_AA_B3LYP'] +
             2 * data[element]['dHf_0_A'])
    dHf_298 = (dHf_0 + data[element]['H_298_H_0_AA_B3LYP'] -
               2 * data[element]['H_298_H_0_A']) * (mol / kcal)
    dist_compound = compound.get_distance(0, 1)
    de = dHf_298 - data[element][xc][1]
    E[element][xc] = de
    if rank == 0:
        print(xc, h, vacuum, dHf_298, data[element][xc][1], de,
              de / data[element][xc][1])
        if element == 'H':
            equal(dHf_298, data[element][xc][1], 0.25,
                  msg=xc + ': ')  # kcal/mol
        elif element == 'O':
            equal(dHf_298, data[element][xc][1], 7.5,
                  msg=xc + ': ')  # kcal/mol
        else:
            equal(dHf_298, data[element][xc][1], 2.15,
                  msg=xc + ': ')  # kcal/mol
        equal(de, E_ref[element][xc], 0.06, msg=xc + ': ')  # kcal/mol
    def read(self, reader):
        """Read state from file."""

        r = reader

        version = r['version']
        
        assert version >= 0.3
    
        self.xc = r['XCFunctional']
        self.nbands = r.dimension('nbands')
        self.spinpol = (r.dimension('nspins') == 2)

        bzk_kc = r.get('BZKPoints', broadcast=True)
        if r.has_array('NBZKPoints'):
            self.kpts = r.get('NBZKPoints', broadcast=True)
            if r.has_array('MonkhorstPackOffset'):
                offset_c = r.get('MonkhorstPackOffset', broadcast=True)
                if offset_c.any():
                    self.kpts = monkhorst_pack(self.kpts) + offset_c
        else:
            self.kpts = bzk_kc

        if version < 4:
            self.symmetry = usesymm2symmetry(r['UseSymmetry'])
        else:
            self.symmetry = {'point_group': r['SymmetryOnSwitch'],
                             'symmorphic': r['SymmetrySymmorphicSwitch'],
                             'time_reversal': r['SymmetryTimeReversalSwitch'],
                             'tolerance': r['SymmetryToleranceCriterion']}

        try:
            self.basis = r['BasisSet']
        except KeyError:
            pass

        if version >= 2:
            try:
                h = r['GridSpacing']
            except KeyError:  # CMR can't handle None!
                h = None
            if h is not None:
                self.h = Bohr * h
            if r.has_array('GridPoints'):
                self.gpts = r.get('GridPoints')
        else:
            if version >= 0.9:
                h = r['GridSpacing']
            else:
                h = None

            gpts = ((r.dimension('ngptsx') + 1) // 2 * 2,
                    (r.dimension('ngptsy') + 1) // 2 * 2,
                    (r.dimension('ngptsz') + 1) // 2 * 2)

            if h is None:
                self.gpts = gpts
            else:
                self.h = Bohr * h

        self.lmax = r['MaximumAngularMomentum']
        self.setups = r['SetupTypes']
        self.fixdensity = r['FixDensity']
        if version <= 0.4:
            # Old version: XXX
            print(('# Warning: Reading old version 0.3/0.4 restart files ' +
                  'will be disabled some day in the future!'))
            self.convergence['eigenstates'] = r['Tolerance']
        else:
            nbtc = r['NumberOfBandsToConverge']
            if not isinstance(nbtc, (int, str)):
                # The string 'all' was eval'ed to the all() function!
                nbtc = 'all'
            if version < 5:
                force_crit = None
            else:
                force_crit = r['ForcesConvergenceCriterion']
                if force_crit is not None:
                    force_crit *= (Hartree / Bohr)
            self.convergence = {'density': r['DensityConvergenceCriterion'],
                                'energy':
                                r['EnergyConvergenceCriterion'] * Hartree,
                                'eigenstates':
                                r['EigenstatesConvergenceCriterion'],
                                'bands': nbtc,
                                'forces': force_crit}

            if version < 1:
                # Volume per grid-point:
                dv = (abs(np.linalg.det(r.get('UnitCell'))) /
                      (gpts[0] * gpts[1] * gpts[2]))
                self.convergence['eigenstates'] *= Hartree**2 * dv

            if version <= 0.6:
                mixer = 'Mixer'
                weight = r['MixMetric']
            elif version <= 0.7:
                mixer = r['MixClass']
                weight = r['MixWeight']
                metric = r['MixMetric']
                if metric is None:
                    weight = 1.0
            else:
                mixer = r['MixClass']
                weight = r['MixWeight']

            if mixer == 'Mixer':
                from gpaw.mixer import Mixer
            elif mixer == 'MixerSum':
                from gpaw.mixer import MixerSum as Mixer
            elif mixer == 'MixerSum2':
                from gpaw.mixer import MixerSum2 as Mixer
            elif mixer == 'MixerDif':
                from gpaw.mixer import MixerDif as Mixer
            elif mixer == 'DummyMixer':
                from gpaw.mixer import DummyMixer as Mixer
            else:
                Mixer = None

            if Mixer is None:
                self.mixer = None
            else:
                self.mixer = Mixer(r['MixBeta'], r['MixOld'], weight)
            
        if version == 0.3:
            # Old version: XXX
            print(('# Warning: Reading old version 0.3 restart files is ' +
                  'dangerous and will be disabled some day in the future!'))
            self.stencils = (2, 3)
            self.charge = 0.0
            fixmom = False
        else:
            self.stencils = (r['KohnShamStencil'],
                             r['InterpolationStencil'])
            if r['PoissonStencil'] == 999:
                self.poissonsolver = FFTPoissonSolver()
            else:
                self.poissonsolver = PoissonSolver(nn=r['PoissonStencil'])
            self.charge = r['Charge']
            fixmom = r['FixMagneticMoment']

        self.occupations = FermiDirac(r['FermiWidth'] * Hartree,
                                      fixmagmom=fixmom)

        try:
            self.mode = r['Mode']
        except KeyError:
            self.mode = 'fd'

        if self.mode == 'pw':
            self.mode = PW(ecut=r['PlaneWaveCutoff'] * Hartree)
            
        if len(bzk_kc) == 1 and not bzk_kc[0].any():
            # Gamma point only:
            if r['DataType'] == 'Complex':
                self.dtype = complex
Beispiel #15
0
        atoms = Atoms('N2', positions=[(0, 0, 0), (0, 0, d_bond + d_disp)])
        atoms.set_pbc(False)
        atoms.center(vacuum=6.0)
        cell_c = np.sum(atoms.get_cell()**2, axis=1)**0.5
        N_c = 8 * np.round(cell_c / (0.2 * 8))
        calc = GPAW(gpts=N_c, nbands=5, basis='dzp',  # TODO xc='PBE'
                    txt=name + '_gs.txt', parallel={'band': 1})
        atoms.set_calculator(calc)

        # QuasiNewton relaxation before we increase the number of bands
        qn = BFGS(atoms, logfile=name + '_gs.log',
                  trajectory=name + '_gs.traj')
        qn.run(0.01, steps=100)

        # Converge enough unoccupied bands for dSCF expansion
        calc.set(nbands=10, spinpol=True, occupations=FermiDirac(0.1),
                 convergence={'bands': -2, 'eigenstates': 1.0e-9})
        atoms.get_potential_energy()
        calc.write(name + '_gs.gpw', mode='all')
        del qn, calc, atoms
        time.sleep(10)

    while not os.path.isfile(name + '_gs.gpw'):
        print('Node %d waiting for %s...' % (world.rank, name + '_gs.gpw'))
        time.sleep(10)
    world.barrier()

    if not os.path.isfile(name + '_es.gpw'):
        # Resume ground state calculator and use as basis for excited state
        calc = GPAW(name + '_gs.gpw',
                    txt=name + '_es.txt',
Beispiel #16
0
L = 7.00

basis = BasisMaker('Na').generate(1, 1, energysplit=0.3)

atoms = Atoms('Na9', pbc=(0, 0, 1), cell=[L, L, 9 * a])
atoms.positions[:9, 2] = [i * a for i in range(9)]
atoms.positions[:, :2] = L / 2.
atoms.center()
pl_atoms1 = range(4)
pl_atoms2 = range(5, 9)
pl_cell1 = (L, L, 4 * a)
pl_cell2 = pl_cell1
t = Transport(h=0.3,
              xc='LDA',
              basis={'Na': basis},
              kpts=(1, 1, 1),
              occupations=FermiDirac(0.1),
              mode='lcao',
              poissonsolver=PoissonSolver(nn=2, relax='GS'),
              txt='Na_lcao.txt',
              mixer=Mixer(0.1, 5, weight=100.0),
              pl_atoms=[pl_atoms1, pl_atoms2],
              pl_cells=[pl_cell1, pl_cell2],
              pl_kpts=(1, 1, 5),
              edge_atoms=[[0, 3], [0, 8]],
              mol_atoms=[4],
              guess_steps=1,
              fixed_boundary=False)
atoms.set_calculator(t)
t.calculate_iv(0.5, 2)
Beispiel #17
0
from gpaw.elf import ELF

# Graphene nanoribbon
ribbon = graphene_nanoribbon(5, 6, type='armchair', saturated=True, vacuum=3.5)

# Gold adsorbate
pos = (ribbon[35].position + ribbon[60].position) / 2.0
pos[1] += 2.2
adsorbate = Atoms('Au', (pos, ))
ribbon += adsorbate
ribbon.center(axis=1, vacuum=3.5)

txt = 'output_p_{}.txt'.format(size)
ribbon.calc = GPAW(
    h=0.22,
    xc='PBE',
    txt=txt,
    occupations=FermiDirac(0.2),
    eigensolver=RMMDIIS(),
)

ribbon.get_potential_energy()

# Calculate electron localization function
elf = ELF(ribbon.calc)
elf.update()
elf_g = elf.get_electronic_localization_function(gridrefinement=2)
if rank == 0:
    write('elf_ribbon.cube', ribbon, data=elf_g)
Beispiel #18
0
        yukawa_gamma=0.83, gpernode=149)

h = 0.35
be = Cluster(Atoms('Be', positions=[[0, 0, 0]]))
be.minimal_box(3.0, h=h)

c = {'energy': 0.05, 'eigenstates': 0.05, 'density': 0.05}

IP = 8.79

xc = HybridXC('LCY-PBE', omega=0.83)
fname = 'Be_rsf.gpw'

calc = GPAW(txt='Be.txt', xc=xc, convergence=c,
            eigensolver=RMMDIIS(), h=h,
            occupations=FermiDirac(width=0.0), spinpol=False)
be.set_calculator(calc)
# energy = na2.get_potential_energy()
# calc.set(xc=xc)
energy_083 = be.get_potential_energy()
(eps_homo, eps_lumo) = calc.get_homo_lumo()
equal(eps_homo, -IP, 0.15)
xc2 = 'LCY-PBE'
energy_075 = calc.get_xc_difference(HybridXC(xc2))
equal(energy_083 - energy_075, 21.13, 0.2, 'wrong energy difference')
calc.write(fname)
calc2 = GPAW(fname)
func = calc2.get_xc_functional()
assert func['name'] == 'LCY-PBE', 'wrong name for functional'
assert func['omega'] == 0.83, 'wrong value for RSF omega'
Beispiel #19
0
def calculate(element, h, vacuum, xc, magmom):

    atom = Atoms([Atom(element, (0, 0, 0))])
    if magmom > 0.0:
        mms = [magmom for i in range(len(atom))]
        atom.set_initial_magnetic_moments(mms)

    atom.center(vacuum=vacuum)

    mixer = MixerSum(beta=0.4)
    if element == 'O':
        mixer = MixerSum(0.4, nmaxold=1, weight=100)
        atom.set_positions(atom.get_positions() + [0.0, 0.0, 0.0001])

    calc_atom = GPAW(h=h,
                     xc=_xc(data[element][xc][2]),
                     experimental={'niter_fixdensity': 2},
                     eigensolver='rmm-diis',
                     occupations=FermiDirac(0.0, fixmagmom=True),
                     mixer=mixer,
                     parallel=dict(augment_grids=True),
                     nbands=-2,
                     txt='%s.%s.txt' % (element, xc))
    atom.set_calculator(calc_atom)

    mixer = Mixer(beta=0.4, weight=100)
    compound = molecule(element + '2')
    if compound == 'O2':
        mixer = MixerSum(beta=0.4)
        mms = [1.0 for i in range(len(compound))]
        compound.set_initial_magnetic_moments(mms)

    calc = GPAW(h=h,
                xc=_xc(data[element][xc][2]),
                experimental={'niter_fixdensity': 2},
                eigensolver='rmm-diis',
                mixer=mixer,
                parallel=dict(augment_grids=True),
                txt='%s2.%s.txt' % (element, xc))
    compound.set_distance(0, 1, data[element]['R_AA_B3LYP'])
    compound.center(vacuum=vacuum)

    compound.set_calculator(calc)

    if data[element][xc][3] == 'hyb_gga':  # only for hybrids
        e_atom = atom.get_potential_energy()
        e_compound = compound.get_potential_energy()

        calc_atom.set(xc=_xc(xc))
        calc.set(xc=_xc(xc))

    e_atom = atom.get_potential_energy()
    e_compound = compound.get_potential_energy()

    dHf_0 = (e_compound - 2 * e_atom + data[element]['ZPE_AA_B3LYP'] +
             2 * data[element]['dHf_0_A'])
    dHf_298 = (dHf_0 + data[element]['H_298_H_0_AA_B3LYP'] -
               2 * data[element]['H_298_H_0_A']) * (mol / kcal)
    de = dHf_298 - data[element][xc][1]
    E[element][xc] = de
    if rank == 0:
        print((xc, h, vacuum, dHf_298, data[element][xc][1], de,
               de / data[element][xc][1]))
        if element == 'H':
            equal(dHf_298, data[element][xc][1], 0.25,
                  msg=xc + ': ')  # kcal/mol
        elif element == 'O':
            equal(dHf_298, data[element][xc][1], 7.5,
                  msg=xc + ': ')  # kcal/mol
        else:
            equal(dHf_298, data[element][xc][1], 2.15,
                  msg=xc + ': ')  # kcal/mol
        equal(de, E_ref[element][xc], 0.06, msg=xc + ': ')  # kcal/mol
Beispiel #20
0
def dscf_collapse_orbitals(paw, nbands_max='occupied', f_tol=1e-4,
                           verify_density=True, nt_tol=1e-5, D_tol=1e-3):

    bd, gd, kd = paw.wfs.bd, paw.wfs.gd, paw.wfs.kd
    if bd.comm.size != 1:
        raise NotImplementedError('Undefined action for band parallelization.')

    f_skn = np.empty((kd.nspins, kd.nibzkpts, bd.nbands), dtype=float)
    for s, f_kn in enumerate(f_skn):
        for k, f_n in enumerate(f_kn):
            kpt_rank, myu = kd.get_rank_and_index(s, k)
            if kd.comm.rank == kpt_rank:
                f_n[:] = paw.wfs.kpt_u[myu].f_n
            kd.comm.broadcast(f_n, kpt_rank)

    # Find smallest band index, from which all bands have negligeble occupations
    n0 = np.argmax(f_skn<f_tol, axis=-1).max()
    assert np.all(f_skn[...,n0:]<f_tol) # XXX use f_skn[...,n0:].sum()<f_tol

    # Read the number of Delta-SCF orbitals
    norbitals = paw.occupations.norbitals
    if debug: mpi_debug('n0=%d, norbitals=%d, bd:%d, gd:%d, kd:%d' % (n0,norbitals,bd.comm.size,gd.comm.size,kd.comm.size))

    if nbands_max < 0:
        nbands_max = n0 + norbitals - nbands_max
    elif nbands_max == 'occupied':
        nbands_max = n0 + norbitals

    assert nbands_max >= n0 + norbitals, 'Too few bands to include occupations.'
    ncut = nbands_max-norbitals

    if debug: mpi_debug('nbands_max=%d' % nbands_max)

    paw.wfs.initialize_wave_functions_from_restart_file() # hurts memmory

    for kpt in paw.wfs.kpt_u:
        mol = kpt.P_ani.keys() # XXX stupid
        (f_o, eps_o, wf_oG, P_aoi,) = dscf_reconstruct_orbitals_k_point(paw, norbitals, mol, kpt)

        assert np.abs(f_o-1).max() < 1e-9, 'Orbitals must be properly normalized.'
        f_o = kpt.ne_o # actual ocupatiion numbers

        # Crop band-data and inject data for Delta-SCF orbitals
        kpt.f_n = np.hstack((kpt.f_n[:n0], f_o, kpt.f_n[n0:ncut]))
        kpt.eps_n = np.hstack((kpt.eps_n[:n0], eps_o, kpt.eps_n[n0:ncut]))
        for a, P_ni in kpt.P_ani.items():
            kpt.P_ani[a] = np.vstack((P_ni[:n0], P_aoi[a], P_ni[n0:ncut]))

        old_psit_nG = kpt.psit_nG
        kpt.psit_nG = gd.empty(nbands_max, dtype=old_psit_nG.dtype)

        if isinstance(old_psit_nG, FileReference):
            assert old_psit_nG.shape[-3:] == wf_oG.shape[-3:], 'Shape mismatch!'

            # Read band-by-band to save memory as full psit_nG may be large
            for n,psit_G in enumerate(kpt.psit_nG):
                if n < n0:
                    full_psit_G = old_psit_nG[n]
                elif n in range(n0,n0+norbitals):
                    full_psit_G = wf_oG[n-n0]
                else:
                    full_psit_G = old_psit_nG[n-norbitals]
                gd.distribute(full_psit_G, psit_G)
        else:
            kpt.psit_nG[:n0] = old_psit_nG[:n0]
            kpt.psit_nG[n0:n0+norbitals] = wf_oG
            kpt.psit_nG[n0+norbitals:] = old_psit_nG[n0:ncut]

        del kpt.ne_o, kpt.c_on, old_psit_nG

    del paw.occupations.norbitals

    # Change various parameters related to new number of bands
    paw.wfs.bd = BandDescriptor(nbands_max, bd.comm, bd.strided)
    if paw.wfs.eigensolver:
        paw.wfs.eigensolver.initialized = False
    del bd

    # Crop convergence criteria nbands_converge to new number of bands
    par = paw.input_parameters
    if 'convergence' in par:
        cc = par['convergence']
        if 'bands' in cc:
            cc['bands'] = min(nbands_max, cc['bands'])

    # Replace occupations class with a fixed variant (gets the magmom right) XXX?!?
    fermilevel, magmom = paw.occupations.fermilevel, paw.occupations.magmom
    paw.occupations = FermiDirac(paw.occupations.width * Hartree, paw.occupations.fixmagmom)
    paw.occupations.fermilevel = fermilevel
    paw.occupations.magmom = magmom
    del fermilevel, magmom

    # For good measure, self-consistency information should be destroyed
    paw.scf.reset()

    if verify_density:
        paw.initialize_positions()

        # Re-calculate pseudo density and watch for changes
        old_nt_sG = paw.density.nt_sG.copy()
        paw.density.calculate_pseudo_density(paw.wfs)
        if debug: mpi_debug('delta-density: %g' % np.abs(old_nt_sG-paw.density.nt_sG).max())
        assert np.abs(paw.density.nt_sG-old_nt_sG).max() < nt_tol, 'Density changed!'

        # Re-calculate atomic density matrices and watch for changes
        old_D_asp = {}
        for a,D_sp in paw.density.D_asp.items():
            old_D_asp[a] = D_sp.copy()
        paw.wfs.calculate_atomic_density_matrices(paw.density.D_asp)
        if debug: mpi_debug('delta-D_asp: %g' % max([0]+[np.abs(D_sp-old_D_asp[a]).max() for a,D_sp in paw.density.D_asp.items()]))
        for a,D_sp in paw.density.D_asp.items():
            assert np.abs(D_sp-old_D_asp[a]).max() < D_tol, 'Atom %d changed!' % a
Beispiel #21
0
# IP for CO using LCY-PBE with gamma=0.81 after
# dx.doi.org/10.1021/acs.jctc.8b00238
IP = 14.31

if setup_paths[0] != '.':
    setup_paths.insert(0, '.')

for atom in ['C', 'O']:
    gen(atom, xcname='PBE', scalarrel=True, exx=True, yukawa_gamma=0.81)

h = 0.30
co = Atoms('CO', positions=[(0, 0, 0), (0, 0, 1.15)])
co.minimal_box(5)

# c = {'energy': 0.005, 'eigenstates': 1e-4}  # Usable values
c = {'energy': 0.1, 'eigenstates': 3, 'density': 3}  # Values for test

calc = GPAW(txt='CO.txt',
            xc='LCY-PBE:omega=0.81',
            convergence=c,
            eigensolver=RMMDIIS(),
            h=h,
            poissonsolver=PoissonSolver(use_charge_center=True),
            occupations=FermiDirac(width=0.0),
            spinpol=False)
co.set_calculator(calc)
co.get_potential_energy()
(eps_homo, eps_lumo) = calc.get_homo_lumo()
equal(eps_homo, -IP, 0.15)
Beispiel #22
0
 def __init__(self, width, *args, **kwargs):
     raise NotImplementedError
     FermiDirac.__init__(self, width, fermi)
     self.set_fermi_level(epsF)
     self.niter = 0
Beispiel #23
0
def wrap_old_gpw_reader(filename):
    warnings.warn('You are reading an old-style gpw-file.  Please check '
                  'the results carefully!')

    r = Reader(filename)

    data = {
        'version': -1,
        'gpaw_version': '1.0',
        'ha': Ha,
        'bohr': Bohr,
        'scf.': {
            'converged': True
        },
        'atoms.': {},
        'wave_functions.': {}
    }

    class DictBackend:
        def write(self, **kwargs):
            data['atoms.'].update(kwargs)

    write_atoms(DictBackend(), read_atoms(r))

    e_total_extrapolated = r.get('PotentialEnergy').item() * Ha
    magmom_a = r.get('MagneticMoments')
    data['results.'] = {
        'energy': e_total_extrapolated,
        'magmoms': magmom_a,
        'magmom': magmom_a.sum()
    }

    if r.has_array('CartesianForces'):
        data['results.']['forces'] = r.get('CartesianForces') * Ha / Bohr

    p = data['parameters.'] = {}

    p['xc'] = r['XCFunctional']
    p['nbands'] = r.dimension('nbands')
    p['spinpol'] = (r.dimension('nspins') == 2)

    bzk_kc = r.get('BZKPoints', broadcast=True)
    if r.has_array('NBZKPoints'):
        p['kpts'] = r.get('NBZKPoints', broadcast=True)
        if r.has_array('MonkhorstPackOffset'):
            offset_c = r.get('MonkhorstPackOffset', broadcast=True)
            if offset_c.any():
                p['kpts'] = monkhorst_pack(p['kpts']) + offset_c
    else:
        p['kpts'] = bzk_kc

    if r['version'] < 4:
        usesymm = r['UseSymmetry']
        if usesymm is None:
            p['symmetry'] = {'time_reversal': False, 'point_group': False}
        elif usesymm:
            p['symmetry'] = {'time_reversal': True, 'point_group': True}
        else:
            p['symmetry'] = {'time_reversal': True, 'point_group': False}
    else:
        p['symmetry'] = {
            'point_group': r['SymmetryOnSwitch'],
            'symmorphic': r['SymmetrySymmorphicSwitch'],
            'time_reversal': r['SymmetryTimeReversalSwitch'],
            'tolerance': r['SymmetryToleranceCriterion']
        }

    p['basis'] = r['BasisSet']

    try:
        h = r['GridSpacing']
    except KeyError:  # CMR can't handle None!
        h = None
    if h is not None:
        p['h'] = Bohr * h
    if r.has_array('GridPoints'):
        p['gpts'] = r.get('GridPoints')

    p['lmax'] = r['MaximumAngularMomentum']
    p['setups'] = r['SetupTypes']
    p['fixdensity'] = r['FixDensity']
    nbtc = r['NumberOfBandsToConverge']
    if not isinstance(nbtc, (int, str)):
        # The string 'all' was eval'ed to the all() function!
        nbtc = 'all'
    p['convergence'] = {
        'density': r['DensityConvergenceCriterion'],
        'energy': r['EnergyConvergenceCriterion'] * Ha,
        'eigenstates': r['EigenstatesConvergenceCriterion'],
        'bands': nbtc
    }
    mixer = r['MixClass']
    weight = r['MixWeight']

    for key in ['basis', 'setups']:
        dct = p[key]
        if isinstance(dct, dict) and None in dct:
            dct['default'] = dct.pop(None)

    if mixer == 'Mixer':
        from gpaw.mixer import Mixer
    elif mixer == 'MixerSum':
        from gpaw.mixer import MixerSum as Mixer
    elif mixer == 'MixerSum2':
        from gpaw.mixer import MixerSum2 as Mixer
    elif mixer == 'MixerDif':
        from gpaw.mixer import MixerDif as Mixer
    elif mixer == 'DummyMixer':
        from gpaw.mixer import DummyMixer as Mixer
    else:
        Mixer = None

    if Mixer is None:
        p['mixer'] = None
    else:
        p['mixer'] = Mixer(r['MixBeta'], r['MixOld'], weight)

    p['stencils'] = (r['KohnShamStencil'], r['InterpolationStencil'])

    vt_sG = r.get('PseudoPotential') * Ha
    ps = r['PoissonStencil']
    if isinstance(ps, int) or ps == 'M':
        poisson = {'name': 'fd'}
        poisson['nn'] = ps
        if data['atoms.']['pbc'] == [1, 1, 0]:
            v1, v2 = vt_sG[0, :, :, [0, -1]].mean(axis=(1, 2))
            if abs(v1 - v2) > 0.01:
                warnings.warn('I am guessing that this calculation was done '
                              'with a dipole-layer correction?')
                poisson['dipolelayer'] = 'xy'
        p['poissonsolver'] = poisson

    p['charge'] = r['Charge']
    fixmom = r['FixMagneticMoment']

    p['occupations'] = FermiDirac(r['FermiWidth'] * Ha, fixmagmom=fixmom)

    p['mode'] = r['Mode']

    if p['mode'] == 'pw':
        p['mode'] = PW(ecut=r['PlaneWaveCutoff'] * Ha)

    if len(bzk_kc) == 1 and not bzk_kc[0].any():
        # Gamma point only:
        if r['DataType'] == 'Complex':
            p['dtype'] = complex

    data['occupations.'] = {
        'fermilevel': r['FermiLevel'] * Ha,
        'split': r.parameters.get('FermiSplit', 0) * Ha,
        'h**o': np.nan,
        'lumo': np.nan
    }

    data['density.'] = {
        'density': r.get('PseudoElectronDensity') * Bohr**-3,
        'atomic_density_matrices': r.get('AtomicDensityMatrices')
    }

    data['hamiltonian.'] = {
        'e_coulomb': r['Epot'] * Ha,
        'e_entropy': -r['S'] * Ha,
        'e_external': r['Eext'] * Ha,
        'e_kinetic': r['Ekin'] * Ha,
        'e_total_extrapolated': e_total_extrapolated,
        'e_xc': r['Exc'] * Ha,
        'e_zero': r['Ebar'] * Ha,
        'potential': vt_sG,
        'atomic_hamiltonian_matrices': r.get('NonLocalPartOfHamiltonian') * Ha
    }
    data['hamiltonian.']['e_total_free'] = (sum(
        data['hamiltonian.'][e] for e in [
            'e_coulomb', 'e_entropy', 'e_external', 'e_kinetic', 'e_xc',
            'e_zero'
        ]))

    if r.has_array('GLLBPseudoResponsePotential'):
        data['hamiltonian.']['xc.'] = {
            'gllb_pseudo_response_potential':
            r.get('GLLBPseudoResponsePotential') * Ha,
            'gllb_dxc_pseudo_response_potential':
            r.get('GLLBDxcPseudoResponsePotential') * Ha / Bohr,
            'gllb_atomic_density_matrices':
            r.get('GLLBAtomicDensityMatrices'),
            'gllb_atomic_response_matrices':
            r.get('GLLBAtomicResponseMatrices'),
            'gllb_dxc_atomic_density_matrices':
            r.get('GLLBDxcAtomicDensityMatrices'),
            'gllb_dxc_atomic_response_matrices':
            r.get('GLLBDxcAtomicResponseMatrices')
        }

    special = [('eigenvalues', 'Eigenvalues'),
               ('occupations', 'OccupationNumbers'),
               ('projections', 'Projections')]

    if r['Mode'] == 'pw':
        special.append(('coefficients', 'PseudoWaveFunctions'))
        try:
            data['wave_functions.']['indices'] = r.get('PlaneWaveIndices')
        except KeyError:
            pass
    elif r['Mode'] == 'fd':
        special.append(('values', 'PseudoWaveFunctions'))
    else:
        special.append(('coefficients', 'WaveFunctionCoefficients'))

    for name, old in special:
        try:
            fd, shape, size, dtype = r.get_file_object(old, ())
        except KeyError:
            continue
        offset = fd
        data['wave_functions.'][name + '.'] = {
            'ndarray': (shape, dtype.name, offset)
        }

    new = ulm.Reader(devnull,
                     data=data,
                     little_endian=r.byteswap ^ np.little_endian)

    for ref in new._data['wave_functions']._data.values():
        try:
            ref.fd = ref.offset
        except AttributeError:
            continue
        ref.offset = 0

    return new
xc = 'PBE'

fit = (5, 0.02)

w = 0.06

ecut = 1200
kd = 8.0

tag = 'dcdft_%s_gpaw_pw' % xc.lower()

task = Task(
    calcfactory=Factory(
        xc=xc,
        mode=PW(ecut),
        occupations=FermiDirac(w),
        maxiter=250,
        kptdensity=kd,
    ),
    tag=tag,
    fit=fit,
    use_lock_files=True,
)

if __name__ == '__main__':
    if element is None:
        keys = set(parameters.keys()).intersection(set(task.collection.names))
        for s in elements_slow:
            keys.remove(s)  # those are slow, run separately
    else:
        keys = [element]
Beispiel #25
0
    def read(self, reader):
        """Read state from file."""

        if isinstance(reader, str):
            reader = gpaw.io.open(reader, 'r')

        r = reader

        version = r['version']

        assert version >= 0.3

        self.xc = r['XCFunctional']
        self.nbands = r.dimension('nbands')
        self.spinpol = (r.dimension('nspins') == 2)

        if r.has_array('NBZKPoints'):
            self.kpts = r.get('NBZKPoints')
        else:
            self.kpts = r.get('BZKPoints')
        self.usesymm = r['UseSymmetry']
        try:
            self.basis = r['BasisSet']
        except KeyError:
            pass
        self.gpts = ((r.dimension('ngptsx') + 1) // 2 * 2,
                     (r.dimension('ngptsy') + 1) // 2 * 2,
                     (r.dimension('ngptsz') + 1) // 2 * 2)
        self.lmax = r['MaximumAngularMomentum']
        self.setups = r['SetupTypes']
        self.fixdensity = r['FixDensity']
        if version <= 0.4:
            # Old version: XXX
            print('# Warning: Reading old version 0.3/0.4 restart files ' +
                  'will be disabled some day in the future!')
            self.convergence['eigenstates'] = r['Tolerance']
        else:
            self.convergence = {
                'density': r['DensityConvergenceCriterion'],
                'energy': r['EnergyConvergenceCriterion'] * Hartree,
                'eigenstates': r['EigenstatesConvergenceCriterion'],
                'bands': r['NumberOfBandsToConverge']
            }
            if version <= 0.6:
                mixer = 'Mixer'
                weight = r['MixMetric']
            elif version <= 0.7:
                mixer = r['MixClass']
                weight = r['MixWeight']
                metric = r['MixMetric']
                if metric is None:
                    weight = 1.0
            else:
                mixer = r['MixClass']
                weight = r['MixWeight']

            if mixer == 'Mixer':
                from gpaw.mixer import Mixer
            elif mixer == 'MixerSum':
                from gpaw.mixer import MixerSum as Mixer
            elif mixer == 'MixerSum2':
                from gpaw.mixer import MixerSum2 as Mixer
            elif mixer == 'MixerDif':
                from gpaw.mixer import MixerDif as Mixer
            elif mixer == 'DummyMixer':
                from gpaw.mixer import DummyMixer as Mixer
            else:
                Mixer = None

            if Mixer is None:
                self.mixer = None
            else:
                self.mixer = Mixer(r['MixBeta'], r['MixOld'], weight)

        if version == 0.3:
            # Old version: XXX
            print('# Warning: Reading old version 0.3 restart files is ' +
                  'dangerous and will be disabled some day in the future!')
            self.stencils = (2, 3)
            self.charge = 0.0
            fixmom = False
        else:
            self.stencils = (r['KohnShamStencil'], r['InterpolationStencil'])
            if r['PoissonStencil'] == 999:
                self.poissonsolver = FFTPoissonSolver()
            else:
                self.poissonsolver = PoissonSolver(nn=r['PoissonStencil'])
            self.charge = r['Charge']
            fixmom = r['FixMagneticMoment']

        self.occupations = FermiDirac(r['FermiWidth'] * Hartree,
                                      fixmagmom=fixmom)

        try:
            self.mode = r['Mode']
        except KeyError:
            self.mode = 'fd'

        try:
            dtype = r['DataType']
            if dtype == 'Float':
                self.dtype = float
            else:
                self.dtype = complex
        except KeyError:
            self.dtype = float
Beispiel #26
0

k = KPoint()


def f(occ, x):
    k.eps_n[0] = x
    n, dnde, x, S = occ.distribution(k, 0.0)
    return n, dnde, S


def test(occ):
    print(occ)
    for e in [-0.3 / Hartree, 0, 0.1 / Hartree, 1.2 / Hartree]:
        n0, d0, S0 = f(occ, e)
        x = 0.000001
        np, dp, Sp = f(occ, e + x)
        nm, dm, Sm = f(occ, e - x)
        d = -(np - nm) / (2 * x)
        dS = Sm - Sp
        dn = np - nm
        print(d - d0, dS - e * dn)
        assert abs(d - d0) < 3e-5
        assert abs(dS - e * dn) < 1e-13


for w in [0.1, 0.5]:
    test(FermiDirac(w))
    for n in range(4):
        test(MethfesselPaxton(w, n))
Beispiel #27
0
 def __init__(self, width, *args, **kwargs):
     raise NotImplementedError
     FermiDirac.__init__(self, width, fermi)
     self.set_fermi_level(epsF)
     self.niter = 0
Beispiel #28
0
    print("#" * 60)
    print("GPAW benchmark: Carbon Fullerenes on a Lead Surface")
    print("  grid spacing: h=%f" % h)
    print("  Brillouin-zone sampling: kpts=" + str(kpts))
    print("  MPI tasks: %d" % size)
    print("  using CUDA (GPGPU): " + str(use_cuda))
    print("  using pyMIC (KNC) : " + str(use_mic))
    print("  using CPU (or KNL): " + str(use_cpu))
    print("#" * 60)
    print("")

# setup parameters
args = {
    'h': h,
    'nbands': -180,
    'occupations': FermiDirac(0.2),
    'kpts': kpts,
    'xc': 'PBE',
    'mixer': Mixer(0.1, 5, 100),
    'eigensolver': 'rmm-diis',
    'maxiter': maxiter,
    'xc_thread': False,
    'txt': txt
}
if use_cuda:
    args['gpu'] = {'cuda': True, 'hybrid_blas': False}
try:
    args['parallel'] = parallel
except:
    pass
Beispiel #29
0
h = 0.3

# No energies - simpley convergence test, esp. for 3d TM

# for atom in ['F', 'Cl', 'Br', 'Cu', 'Ag']:
for atom in ['Ti']:
    gen(atom, xcname='PBE', scalarrel=False, exx=True)
    work_atom = Cluster(Atoms(atom, [(0, 0, 0)]))
    work_atom.minimal_box(4, h=h)
    work_atom.translate([0.01, 0.02, 0.03])
    work_atom.set_initial_magnetic_moments([2.0])
    calculator = GPAW(convergence={
        'energy': 0.01,
        'eigenstates': 3,
        'density': 3
    },
                      eigensolver=RMMDIIS(),
                      poissonsolver=PoissonSolver(use_charge_center=True),
                      occupations=FermiDirac(width=0.0, fixmagmom=True),
                      h=h,
                      maxiter=35)  # Up to 24 are needed by now
    calculator.set(xc=HybridXC('PBE0'))
    calculator.set(txt=atom + '-PBE0.txt')
    work_atom.set_calculator(calculator)
    try:
        work_atom.get_potential_energy()
    except KohnShamConvergenceError:
        pass
    assert calculator.scf.converged, 'Calculation not converged'