Ejemplo n.º 1
0
def read_slakoformat(filename):
    """
    read Slater Koster tables from different file formats, which
    are recognized by the file extension.
    
    The following extensions are supported:
    *.skf    used by DFTB+
    *.par    used by hotbit
    *.py     

    Paramters:
    ==========
    filename: path to Slater Koster file

    Returns:
    ========
    sk

    The Slater Koster data is stored in attributes of sk:
    sk.Z1, sk.Z2, sk.d, sk.S, sk.H    
    """
    from os.path import exists, basename, dirname, join

    if ".skf" in filename:
        filename_AB = filename
        # load Slater Koster integrals for A atom
        sk = read_slakoformat_skf(filename_AB, sk=None, atom_order="AB")
        at1, at2 = basename(filename).replace(".skf", "").split("-")
        # append Slater Koster integrals for B atom
        filename_BA = join(dirname(filename), "%s-%s.skf" % (at2, at1))
        sk = read_slakoformat_skf(filename_BA, sk=sk, atom_order="BA")
        return sk
    elif ".par" in filename:
        atom_order = "AB"
        if not exists(filename):
            # file file A_B.par does not exist, look for file B_A.par
            at1, at2 = basename(filename).replace(".par", "").split("_")
            filename_BA = join(dirname(filename), "%s_%s.par" % (at2, at1))
            print "parameter file %s does not exist -> try to load %s" % (
                filename, filename_BA)
            filename = filename_BA
            atom_order = "BA"
            assert exists(filename)
        sk = read_slakoformat_par(filename, atom_order=atom_order)
        return sk
    elif ".py" in filename:
        # access dictionary by .-notation
        mod = utils.dotdic()
        execfile(filename, mod)
        #        mod = weird_sign_change(mod)
        return mod
def read_repulsive_potential(filename):
    """
    read repulsive potential in the format used by Hotbit, DFTBaby or DFTB+
    """
    from os.path import exists, basename, dirname, join
    if ".par" in filename:
        # Hotbit's format
        at1, at2 = basename(filename).replace(".par", "").split("_")
        if not exists(filename):
            # file file A_B.par does not exist, look for file B_A.par
            filename_BA = join(dirname(filename), "%s_%s.par" % (at2, at1))
            print "parameter file %s does not exist -> try to load %s" % (
                filename, filename_BA)
            filename = filename_BA
        data_blocks = hotbit_format.parseHotbitParameters(filename)
        mod = ReppotModule()
        mod.d = data_blocks["repulsive_potential"][:, 0]
        mod.Vrep = data_blocks["repulsive_potential"][:, 1]
        mod.Z1 = AtomicData.atomic_number(at1)
        mod.Z2 = AtomicData.atomic_number(at2)
        return mod
    elif ".py" in filename:
        # DFTBaby format
        # access dictionary by .-notation
        mod = utils.dotdic()
        execfile(filename, mod)
        return mod
    elif ".skf" in filename:
        # DFTB+ format, only the Splines part is read
        at1, at2 = basename(filename).replace(".skf", "").split("-")
        if not exists(filename):
            # file file A-B.skf does not exist, look for file B-A.skf
            filename_BA = join(dirname(filename), "%s-%s.skf" % (at2, at1))
            print "parameter file %s does not exist -> try to load %s" % (
                filename, filename_BA)
            filename = filename_BA
        fh = open(filename)
        lines = fh.readlines()
        fh.close()
        # find section with repulsive potential
        for i, l in enumerate(lines):
            if l.strip() == "Spline":
                break
        else:
            raise Exception("No 'Spline' section found in parameter file %s" %
                            filename)
        # Line 2:
        nInt, cutoff = lines[i + 1].strip().split()
        nInt, cutoff = int(nInt), float(cutoff)
        # Line 3: V(r < r0) = exp(-a1*r+a2) + a3   is r too small to be covered by the spline
        a1, a2, a3 = map(float, lines[i + 2].strip().split())
        # Line 4 to 4+nInt-2
        rs = np.zeros(nInt)
        cs = np.zeros((4, nInt))
        for j in range(0, nInt):
            # spline for the range [rj=start,r_(j+1)=end]
            # V(r_j <= r < r_(j+1)) = c0 + c1*(r-r0) + c2*(r-r0)^2 + c3*(r-r0)^3
            start, end, c0, c1, c2, c3 = map(
                float, lines[i + 3 + j].strip().split()[:6])
            rs[j] = start
            cs[:, j] = np.array([c0, c1, c2, c3])
        # V(r_nInt < r) = 0.0
        assert end == cutoff
        # Now we evaluate the spline on a equidistant grid
        Npts = 100
        d = np.linspace(0.0, cutoff, Npts)
        Vrep = np.zeros(Npts)
        j = 0
        for i, di in enumerate(d):
            if (di < rs[0]):
                Vrep[i] = np.exp(-a1 * di + a2) + a3
            else:
                # find interval such that r[j] <= di < r[j+1]
                while (di >= rs[j + 1]) and j < nInt - 2:
                    j += 1
                if j < nInt - 2:
                    assert rs[j] <= di < rs[j + 1]
                    c0, c1, c2, c3 = cs[:, j]
                    Vrep[i] = c0 + c1 * (di - rs[j]) + c2 * (
                        di - rs[j])**2 + c3 * (di - rs[j])**3
                else:
                    Vrep[i] = 0.0
        # create python module
        mod = ReppotModule()
        mod.d = d
        mod.Vrep = Vrep
        mod.Z1 = AtomicData.atomic_number(at1)
        mod.Z2 = AtomicData.atomic_number(at2)
        return mod
    else:
        raise Exception("Format of %s not understood" % filename)
Ejemplo n.º 3
0
    xlabel("r / bohr", fontsize=15)
    print "Atom %s" % AtomicData.atom_names[atom.Z-1]
    print "========"
    for i,orb_name in enumerate(atom.orbital_names):
        print "Orbital %s:  %s  %s" % (orb_name, \
                         ("%2.5f Hartree" % atom.energies[i]).rjust(15), \
                         ("%2.5f eV" % (atom.energies[i]*AtomicData.hartree_to_eV)).rjust(20))
        plot(atom.r, atom.radial_wavefunctions[i], lw=2.5, label="%s en=%s" % (orb_name, atom.energies[i]))
        # compare with hotbit
        if elmfile != None and hbdata.has_key("radial_wavefunction_%s" % orb_name):
            ru = hbdata["radial_wavefunction_%s" % orb_name]
            en = hbdata["orbital_energy_%s" % orb_name]
            plot(ru[:,0], ru[:,1], ls="-.", label="%s en=%s (unconfined)" % (orb_name, en))
    legend()
    show()
#    savefig(pngfile)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print "Usage: python %s <pseudo atom module>.py [<.elm file for comparison>]" % sys.argv[0]
        print "Plots the atomic orbitals of a pseudo atom."
        exit(-1)
    modfile = sys.argv[1]
    if len(sys.argv) > 2:
        elmfile = sys.argv[2]
    else:
        elmfile = None
    mod = utils.dotdic()
    execfile(modfile, mod)
    plot_pseudoatom(mod, "/tmp/%s.png" % AtomicData.atom_names[mod.Z-1], elmfile)