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)
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)