Esempio n. 1
0
def run(name):
    Calculator = get_calculator(name)
    par = required.get(name, {})
    calc = Calculator(
        label=name + '_bandgap',
        xc='PBE',
        # abinit, aims, elk - do not recognize the syntax below:
        # https://trac.fysik.dtu.dk/projects/ase/ticket/98
        # kpts={'size': kpts, 'gamma': True}, **par)
        kpts=kpts,
        **par)
    si = bulk('Si', crystalstructure='diamond', a=5.43)
    si.calc = calc
    si.get_potential_energy()
    print(name, bandgap(si.calc))
    del si.calc
    # test spin-polarization
    calc = Calculator(
        label=name + '_bandgap_spinpol',
        xc='PBE',
        # abinit, aims, elk - do not recognize the syntax below:
        # https://trac.fysik.dtu.dk/projects/ase/ticket/98
        # kpts={'size': kpts, 'gamma': True}, **par)
        kpts=kpts,
        **par)
    si.set_initial_magnetic_moments([-0.1, 0.1])
    # this should not be necessary in the new ase interface standard ...
    if si.get_initial_magnetic_moments().any():  # spin-polarization
        if name == 'aims':
            calc.set(spin='collinear')
        if name == 'elk':
            calc.set(spinpol=True)
    si.set_calculator(calc)
    si.get_potential_energy()
    print(name, bandgap(si.calc))
Esempio n. 2
0
def run(name):
    Calculator = get_calculator(name)
    par = required.get(name, {})
    calc = Calculator(label=name + '_bandgap', xc='PBE',
                      # abinit, aims, elk - do not recognize the syntax below:
                      # https://trac.fysik.dtu.dk/projects/ase/ticket/98
                      # kpts={'size': kpts, 'gamma': True}, **par)
                      kpts=kpts, **par)
    si = bulk('Si', crystalstructure='diamond', a=5.43)
    si.calc = calc
    si.get_potential_energy()
    print(name, bandgap(si.calc))
    del si.calc
    # test spin-polarization
    calc = Calculator(label=name + '_bandgap_spinpol', xc='PBE',
                      # abinit, aims, elk - do not recognize the syntax below:
                      # https://trac.fysik.dtu.dk/projects/ase/ticket/98
                      # kpts={'size': kpts, 'gamma': True}, **par)
                      kpts=kpts, **par)
    si.set_initial_magnetic_moments([-0.1, 0.1])
    # this should not be necessary in the new ase interface standard ...
    if si.get_initial_magnetic_moments().any():  # spin-polarization
        if name == 'aims':
            calc.set(spin='collinear')
        if name == 'elk':
            calc.set(spinpol=True)
    si.set_calculator(calc)
    si.get_potential_energy()
    print(name, bandgap(si.calc))
Esempio n. 3
0
 def test_bs(self):
     sb = StructureBuilder()
     atoms, *_ = sb.get_structure("C", "diamond")
     # print(atoms)
     base_dir = os.path.join(os.path.dirname(__file__),
                             "../../tmp/C-class/")
     m_calc = MaterCalc(atoms=atoms,
                        base_dir=base_dir)
     self.assertTrue(m_calc.relax(fmax=0.002))  # Very tight limit!
     self.assertTrue(m_calc.ground_state())
     # get the PBE BS
     lattice_type = get_cellinfo(m_calc.atoms.cell).lattice
     self.assertTrue(lattice_type in special_paths.keys())
     kpts_bs = dict(path=special_paths[lattice_type],
                    npoints=120)
     # HSE06 base generate
     gs_file = os.path.join(base_dir, "gs.gpw")
     _calc = GPAW(restart=gs_file)
     atoms = _calc.atoms.copy()
     calc = GPAW(**_calc.parameters)
     calc.set(kpts=dict(gamma=True,
                        density=4))  # low density calculations
     calc.atoms = atoms
     del _calc
     calc.get_potential_energy()
     calc.write(os.path.join(base_dir, "hse.gpw"), mode="all")
     calc = GPAW(restart=os.path.join(base_dir, "hse.gpw"),
                 txt=None)
     ns = calc.get_number_of_spins()
     nk = len(calc.get_ibz_k_points())
     nbands = calc.get_number_of_bands()
     eigen_pbe = numpy.array([[calc.get_eigenvalues(spin=s,
                                                    kpt=k) \
                               for k in range(nk)]\
                              for s in range(ns)])
     parprint("EIGEN_PBE", eigen_pbe.shape)
     vxc_pbe = vxc(calc, "PBE")
     parprint("VXC_PBE", vxc_pbe.shape)
     # world.barrier()
     # HSE06 now
     calc_hse = EXX(os.path.join(base_dir, "hse.gpw"),
                    xc="HSE06",
                    bands=[0, nbands])
     calc_hse.calculate()
     vxc_hse = calc_hse.get_eigenvalue_contributions()
     parprint(vxc_hse.shape)
     parprint(vxc_hse)
     eigen_hse = eigen_pbe - vxc_pbe + vxc_hse
     
     # HSE bandgap from just kpts
     bg_hse_min, *_ = bandgap(eigenvalues=eigen_hse,
                              efermi=calc.get_fermi_level(),
                              direct=False)
     bg_hse_dir, *_ = bandgap(eigenvalues=eigen_hse,
                              efermi=calc.get_fermi_level(),
                              direct=True)
     parprint("HSE: E_min \t E_dir")
     parprint("{:.3f}\t{:.3f}".format(bg_hse_min, bg_hse_dir))
     """
Esempio n. 4
0
 def summary(self):
     efermi = self.occupations.fermilevel
     self.hamiltonian.summary(efermi, self.log)
     self.density.summary(self.atoms, self.occupations.magmom, self.log)
     self.occupations.summary(self.log)
     self.wfs.summary(self.log)
     try:
         bandgap(self, output=self.log.fd, efermi=efermi * Ha)
     except ValueError:
         pass
     self.log.fd.flush()
Esempio n. 5
0
def get_bulk(name, proto):
    # Get bulk properties
    dir_root = os.path.join("../../data/2D-bulk/{}-{}".format(name, proto))
    gpw_file = os.path.join(dir_root, "gs.gpw")
    traj_file = os.path.join(dir_root, "{}-{}_relax.traj".format(name, proto))
    eps_file = os.path.join(dir_root, "eps_df.npz")
    if (not os.path.exists(gpw_file)) or (not os.path.exists(eps_file)):
        return None
    else:
        try:
            d = Trajectory(traj_file)[-1].cell[-1][-1]
        except Exception:
            print(Exception)
            c_atoms = read(gpw_file)
            # calc = GPAW(gpw_file)
            d = c_atoms.cell[-1][-1]
            # d = calc.get_atoms().cell[-1][-1]
        f = numpy.load(eps_file)
        eps_xx = f["eps_x"][0].real
        eps_zz = f["eps_z"][0].real
        calc = GPAW(gpw_file)
        try:
            E_GGA, *_ = bandgap(calc)
        except Exception:
            E_GGA = None
        return d, eps_xx, eps_zz, E_GGA
Esempio n. 6
0
def test(e_skn):
    c = Calculator(e_skn)
    if c.ns == 1:
        result = [bandgap(c), bandgap(c, direct=True)]
        return [(gap, k1, k2) for gap, (s1, k1, n1), (s2, k2, n2) in result]
    result = [bandgap(c), bandgap(c, direct=True),
              bandgap(c, spin=0), bandgap(c, direct=True, spin=0),
              bandgap(c, spin=1), bandgap(c, direct=True, spin=1)]
    for gap, (s1, k1, n1), (s2, k2, n2) in result:
        if k1 is not None:
            assert gap == e_skn[s2][k2][n2] - e_skn[s1][k1][n1]
    return [(gap, (s1, k1), (s2, k2))
            for gap, (s1, k1, n1), (s2, k2, n2) in result]
Esempio n. 7
0
    def test_relax_single(self):
        sb = StructureBuilder()
        atoms, *_ = sb.get_structure("C", "diamond")
        # print(atoms)
        m_calc = MaterCalc(atoms=atoms, base_dir="../../tmp/C-class/")
        m_calc.relax(fmax=0.002)  # Very tight limit!
        m_calc.ground_state()

        # self.assertTrue(res)
        base_dir = "../../tmp/C-class/"
        gpw_name = os.path.join(base_dir, "gs.gpw")
        self.assertTrue(os.path.exists(gpw_name))
        calc = GPAW(restart=gpw_name, txt="gp.txt")
        # PBE bandgap
        bg_pbe_min, *_ = bandgap(calc, direct=False)
        bg_pbe_dir, *_ = bandgap(calc, direct=True)
        # gllbsc
        calc_gllb = GPAW(**calc.parameters)
        calc_gllb.atoms = calc.atoms
        calc_gllb.set(xc="GLLBSC", txt="gllb.txt")
        calc_gllb.get_potential_energy()  # SC calculation
        response = calc_gllb.hamiltonian.xc.xcs["RESPONSE"]
        response.calculate_delta_xc()
        EKs, Dxc = response.calculate_delta_xc_perturbation()
        gllb_gap = EKs + Dxc

        parprint("Eg-PBE-min, Eg-PBE-dir, Eg-gllb")
        parprint(bg_pbe_min, bg_pbe_dir, gllb_gap)
        # Use kpts?
        ibz_kpts = calc.get_ibz_k_points()
        e_kn = numpy.array([calc.get_eigenvalues(kpt=k) \
                            for k in range(len(ibz_kpts))])
        efermi = calc.get_fermi_level()
        e_kn[e_kn > efermi] += Dxc
        gllb_gap_min = bandgap(eigenvalues=e_kn, efermi=efermi, direct=False)
        gllb_gap_dir = bandgap(eigenvalues=e_kn, efermi=efermi, direct=True)

        parprint("Efermi", efermi)
        parprint("Eg-gllb-min, Eg-gllb-dir")
        parprint(gllb_gap_min, gllb_gap_dir)
Esempio n. 8
0
def test(e_skn):
    c = Calculator(e_skn)
    if c.ns == 1:
        result = [bandgap(c), bandgap(c, direct=True)]
        return [(gap, k1, k2) for gap, (s1, k1, n1), (s2, k2, n2) in result]
    result = [
        bandgap(c),
        bandgap(c, direct=True),
        bandgap(c, spin=0),
        bandgap(c, direct=True, spin=0),
        bandgap(c, spin=1),
        bandgap(c, direct=True, spin=1)
    ]
    return [(gap, (s1, k1), (s2, k2))
            for gap, (s1, k1, n1), (s2, k2, n2) in result]
Esempio n. 9
0
def test_bandgap():
    from ase.dft.bandgap import bandgap

    class Test:
        def get_ibz_k_points(self):
            return [(0, 0, 0)]

        def get_number_of_spins(self):
            return 2

        def get_eigenvalues(self, kpt, spin):
            return [-10, spin, spin + 2.0]

        def get_fermi_level(self):
            return 0.5

    gaps = [2, 11, 1, 2, 11, 1]

    calc = Test()
    for direct in [0, 1]:
        for spin in [0, 1, None]:
            gap, k1, k2 = bandgap(calc, direct=direct, spin=spin)
            print(gap, k1, k2)
            assert gap == gaps.pop(0)
Esempio n. 10
0
 def get_bandgap(self):
     print("Calculating bandgap.")
     gap,p1,p2 = bandgap(self.system.calc);
     direct_gap,direct_p1,direct_p2 = bandgap(self.system.calc,direct=True);
     self.bandgap = gap
     self.bandgap_direct = direct_gap
Esempio n. 11
0
from ase.dft.bandgap import bandgap


class Test:
    def get_ibz_k_points(self):
        return [(0, 0, 0)]

    def get_number_of_spins(self):
        return 2

    def get_eigenvalues(self, kpt, spin):
        return [-10, spin, spin + 2.0]

    def get_fermi_level(self):
        return 0.5


gaps = [2, 11, 1, 2, 11, 2]

calc = Test()
for direct in [0, 1]:
    for spin in [0, 1, None]:
        gap, k1, k2 = bandgap(calc, direct=direct, spin=spin)
        print(gap, k1, k2)
        assert gap == gaps.pop(0)
# ASE
from ase import Atoms
from ase.dft.bandgap import bandgap
from ase.parallel import world

# GPAW
from gpaw import GPAW, restart

# Restart electronicSi calculator and calculate bandgap

_, calc = restart('Si_electrons.gpw')

# Indirect bandgap
gap, p1, p2 = bandgap(calc, direct=False, output='indirectBandgap.txt')
print(f'Indirect bandgap: {gap:.2f} eV')
gap, p1, p2 = bandgap(calc, direct=True, output='directBandgap.txt')
print(f'Direct bandgap: {gap:.2f} eV')
Esempio n. 13
0
    def test_bs(self):
        sb = StructureBuilder()
        atoms, *_ = sb.get_structure("Si", "diamond")
        # print(atoms)
        base_dir = os.path.join(os.path.dirname(__file__),
                                "../../tmp/Si-class/")
        m_calc = MaterCalc(atoms=atoms, base_dir=base_dir)
        self.assertTrue(m_calc.relax(fmax=0.002))  # Very tight limit!
        self.assertTrue(m_calc.ground_state())
        # get the PBE BS
        lattice_type = get_cellinfo(m_calc.atoms.cell).lattice
        self.assertTrue(lattice_type in special_paths.keys())
        kpts_bs = dict(path=special_paths[lattice_type], npoints=120)
        gpw_name = os.path.join(base_dir, "gs.gpw")
        self.assertTrue(os.path.exists(gpw_name))
        calc_bs = GPAW(restart=gpw_name,
                       kpts=kpts_bs,
                       fixdensity=True,
                       symmetry='off',
                       txt=os.path.join(base_dir, "pbe-bs.txt"))
        calc_bs.get_potential_energy()
        # PBE bandgap
        bg_pbe_min, *_ = bandgap(calc_bs, direct=False)
        bg_pbe_dir, *_ = bandgap(calc_bs, direct=True)
        calc_bs.write(os.path.join(base_dir, "pbe-bs.gpw"))
        bs_pbe = calc_bs.band_structure()
        bs_pbe.plot(emin=-10,
                    emax=10,
                    filename=os.path.join(base_dir, "pbe-bs.png"))

        # get the gllbsc by steps
        calc_ = GPAW(restart=gpw_name)
        calc_gllb = GPAW(**calc_.parameters)
        calc_gllb.set(xc="GLLBSC", txt=os.path.join(base_dir, "gllb-gs.txt"))
        calc_gllb.atoms = calc_.atoms
        del calc_
        calc_gllb.get_potential_energy()  # SC calculation
        calc_gllb.write("gllb-gs.gpw")
        calc_gllb_bs = GPAW(restart="gllb-gs.gpw",
                            kpts=kpts_bs,
                            fixdensity=True,
                            symmetry="off",
                            txt=os.path.join(base_dir, "gllb-bs.txt"))
        world.barrier()
        calc_gllb_bs.get_potential_energy()
        homolumo = calc_gllb_bs.get_homo_lumo()
        bg_gllb_ks = homolumo[1] - homolumo[0]
        response = calc_gllb_bs.hamiltonian.xc.xcs["RESPONSE"]
        response.calculate_delta_xc(homolumo / Ha)
        EKs, Dxc = response.calculate_delta_xc_perturbation()
        bg_gllb_deltaxc = EKs + Dxc

        ibz_kpts = calc_gllb_bs.get_ibz_k_points()
        e_kn = numpy.array([calc_gllb_bs.get_eigenvalues(kpt=k) \
                            for k in range(len(ibz_kpts))])
        efermi = calc_gllb_bs.get_fermi_level()
        e_kn[e_kn > efermi] += Dxc
        bg_gllb_min, *_ = bandgap(eigenvalues=e_kn,
                                  efermi=efermi,
                                  direct=False)
        bg_gllb_dir, *_ = bandgap(eigenvalues=e_kn, efermi=efermi, direct=True)

        parprint("PBE: E_min \t E_dir")
        parprint("{:.3f}\t{:.3f}".format(bg_pbe_min, bg_pbe_dir))
        parprint("Gllb: EKS \t E_deltaxc")
        parprint("{:.3f}\t{:.3f}".format(bg_gllb_ks, bg_gllb_deltaxc))
        parprint("Gllb: E_min \t E_dir")
        parprint("{:.3f}\t{:.3f}".format(bg_gllb_min, bg_gllb_dir))
        bs_gllb = calc_gllb_bs.band_structure()
        bs_gllb.energies[bs_gllb.energies > bs_gllb.reference] += Dxc
        bs_gllb.plot(emin=-10,
                     emax=10,
                     filename=os.path.join(base_dir, "gllb-bs.png"))

        calc_gllb_bs.write(os.path.join(base_dir, "gllb-bs.gpw"))
Esempio n. 14
0
structures = ['Si', 'Ge', 'C']
db = connect('database.db')

for f in structures:
    db.write(bulk(f))

for row in db.select():
    atoms = row.toatoms()
    calc = GPAW(mode=PW(400),
                kpts=(4, 4, 4),
                txt=f'{row.formula}-gpaw.txt',
                xc='LDA')
    atoms.calc = calc
    atoms.get_stress()
    filter = ExpCellFilter(atoms)
    opt = BFGS(filter)
    opt.run(fmax=0.05)
    db.write(atoms=atoms, relaxed=True)

for row in db.select(relaxed=True):
    atoms = row.toatoms()
    calc = GPAW(mode=PW(400),
                kpts=(4, 4, 4),
                txt=f'{row.formula}-gpaw.txt',
                xc='LDA')
    atoms.calc = calc
    atoms.get_potential_energy()
    bg, _, _ = bandgap(calc=atoms.calc)
    db.update(row.id, bandgap=bg)
Esempio n. 15
0
atoms = Atoms(symbols='Ni2O2',
              pbc=True,
              cell=(b, b, a),
              positions=[(0, 0, 0), (b / 2, b / 2, a / 2), (0, 0, a / 2),
                         (b / 2, b / 2, 0)],
              magmoms=(m, -m, 0, 0))

name = 'ni2o2'
for setup in ['10', '10:d,6.0']:
    calc = GPAW(mode='pw',
                occupations=FermiDirac(width=0.05),
                setups={'Ni': setup},
                convergence={
                    'eigenstates': 8e-4,
                    'density': 1.0e-2,
                    'energy': 0.1
                },
                txt=name + '.txt',
                kpts=(k, k, k),
                xc='oldPBE')
    atoms.calc = calc
    e = atoms.get_potential_energy()
    gap, _, _ = bandgap(calc)
    print(name, gap)
    if name == 'ni2o2':
        equal(gap, 0.8, 0.1)
    else:
        equal(gap, 4.7, 0.2)
    name += '+U'