def get_active_space(xyzfile, optionfile): """calculates the active space for a given molecule and excited state (see http://www.dftbaby.chemie.uni-wuerzburg.de/DFTBaby/mdwiki.html#!WIKI/main_page.md, Active Space) not implemented in CAST because no use for ground state calculations for ground state calculations the active space can be set as small as desired""" outputfile = open("output_dftb.txt", "a") # redirect output to file sys.stdout = outputfile try: options = read_options(optionfile) # read options atomlist = XYZ.read_xyz(xyzfile)[0] # read structure init_options = extract_options(options, TD_INIT_OPTIONLIST) td_options = extract_options(options, TD_OPTIONLIST) kwds = XYZ.extract_keywords_xyz(xyzfile) tddftb = LR_TDDFTB(atomlist, **init_options) # create object tddftb.setGeometry(atomlist, charge=kwds.get("charge", 0.0)) tddftb.getEnergies(**td_options) # calculate energies occ, virt = tddftb.determineActiveSpace() return str((occ, virt)) except: print sys.exc_info() return "error"
def calc_gradients(xyzfile, optionfile): """calculates DFTB energies and gradients for a molecule in the xyz_file with the options given in the optionfile""" outputfile = open("output_dftb.txt", "a") # redirect output to file sys.stdout = outputfile try: options = read_options(optionfile) # read options atomlist = XYZ.read_xyz(xyzfile)[0] # read structure init_options = extract_options(options, TD_INIT_OPTIONLIST) td_options = extract_options(options, TD_OPTIONLIST) grad_options = extract_options(options, GRAD_OPTIONS) kwds = XYZ.extract_keywords_xyz(xyzfile) tddftb = LR_TDDFTB(atomlist, **init_options) # create object tddftb.setGeometry(atomlist, charge=kwds.get("charge", 0.0)) tddftb.getEnergies(**td_options) # calculate energies grad = Gradients(tddftb) # calculate gradients grad.getGradients(**grad_options) energies = list(tddftb.dftb2.getEnergies()) # get partial energies if tddftb.dftb2.long_range_correction == 1: # add long range correction to partial energies energies.append(tddftb.dftb2.E_HF_x) return str(energies) except: print sys.exc_info() return "error"
def calc_energies(xyzfile, optionfile): """calculates DFTB energies for a molecule in the xyz_file with the options given in the optionfile""" outputfile = open("output_dftb.txt", "a") # redirect output to file sys.stdout = outputfile try: options = read_options(optionfile) # read options atomlist = XYZ.read_xyz(xyzfile)[0] # read structure kwds = XYZ.extract_keywords_xyz(xyzfile) dftb2 = DFTB2(atomlist, **options) # create dftb object dftb2.setGeometry(atomlist, charge=kwds.get("charge", 0.0)) scf_options = extract_options(options, SCF_OPTIONLIST) # calculate energy dftb2.getEnergy(**scf_options) energies = list(dftb2.getEnergies()) # get partial energies if dftb2.long_range_correction == 1: # add long range correction to partial energies energies.append(dftb2.E_HF_x) return str(energies) except: print sys.exc_info() return "error"
def dupliverts(xyz_file, frag_links_file, out_xyz_file): """ """ fragments = load_fragments(frag_links_file) fragnames = fragments.keys() # copy keywords like charge, etc. kwds = XYZ.extract_keywords_xyz(xyz_file) title = reduce(lambda a, b: a + " " + b, ["%s=%s " % (k, v) for (k, v) in kwds.iteritems()], "") # for i, fraglist in enumerate(read_xyz_rotation_it(xyz_file)): if i == 0: mode = 'w' else: mode = 'a' XYZ.write_xyz(out_xyz_file, [substitute_fragments(fraglist, fragnames, fragments)], title=title, mode=mode)
exit(-1) geom_file = args[0] energy_file = args[1] force_file = args[2] print("Compute forces with DFTB") print("========================") print("") fh_en = open(energy_file, "w") print("# ELECTRONIC ENERGY / HARTREE", file=fh_en) # first geometry atomlist = XYZ.read_xyz(geom_file)[0] # read charge from title line in .xyz file kwds = XYZ.extract_keywords_xyz(geom_file) charge = kwds.get("charge", opts.charge) pes = PotentialEnergySurfaces(atomlist, charge=charge) # dftbaby needs one excited states calculation to set all variables x = XYZ.atomlist2vector(atomlist) pes.getEnergies(x) for i, atomlist in enumerate(XYZ.read_xyz(geom_file)): # compute electronic ground state forces with DFTB x = XYZ.atomlist2vector(atomlist) en = pes.getEnergy_S0(x) # total ground state energy including repulsive potential en_tot = en[0] print("Structure %d enTot= %s Hartree" % (i, en_tot)) # electronic energy without repulsive potential
import sys import os if len(sys.argv) < 3: print "Usage: %s .xyz-file .ff-file" % (os.path.basename(sys.argv[0])) print " assigns atom types automatically for geometry in .xyz-file." print "" print " This script simply adds a 5th column with the atom type" print " and writes the result to the .ff-file ." print " " print " WARNING: The type assignment and the force field implementation itself probably have lots of bugs!" exit(-1) # laod xyz-file xyz_file = sys.argv[1] atomlist = XYZ.read_xyz(xyz_file)[0] # find total charge kwds = XYZ.extract_keywords_xyz(xyz_file) charge = kwds.get("charge", 0.0) nat = len(atomlist) # determine bond orders print "connectivity matrix" ConMat = XYZ.connectivity_matrix(atomlist, search_neighbours=200) print "bond order assignment" bondsTuples, bond_orders, lone_pairs, formal_charges = BondOrders.assign_bond_orders( atomlist, ConMat, charge=charge) # list of bond orders bond_orders_atomwise = [[] for i in range(0, nat)] # names of atoms connected to each bonded_atomnames = [[] for i in range(0, nat)] for i, (atI, atJ) in enumerate(bondsTuples): BO = bond_orders[i]
# chemical equation educts_str = " + ".join([ "%d %s " % (coef, educt) for (coef, educt) in zip(coefs_educts, educts) ]) products_str = " + ".join([ "%d %s " % (-coef, prod) for (coef, prod) in zip(coefs_products, products) ]) reaction_str = educts_str + " <---> " + products_str # compute reference energy en_ref = 0.0 for coef, mol in zip(coefs_educts + coefs_products, educts + products): en = float( XYZ.extract_keywords_xyz(os.path.join("REFERENCE", mol + ".xyz"))["energy"]) en_ref -= coef * en # compute DFTB energy en_dftb = 0.0 for coef, mol in zip(coefs_educts + coefs_products, educts + products): en = float( XYZ.extract_keywords_xyz(os.path.join("DFTB", mol + ".xyz"))["energy"]) en_dftb -= coef * en # convert from Hartree to kcal/mol en_ref *= AtomicData.hartree_to_kcalmol en_dftb *= AtomicData.hartree_to_kcalmol print("%40.40s %+15.1f %+15.1f" %
def hessian(xyzfile, optionfile): """calculates hessian matrix""" outputfile = open("output_dftb.txt", "a") # redirect output to file sys.stdout = outputfile try: I = 0 # index of electronic state (ground state) atomlist = XYZ.read_xyz(xyzfile)[0] # read xyz file kwds = XYZ.extract_keywords_xyz(xyzfile) # read keywords (charge) options = read_options(optionfile) # read options scf_options = extract_options(options, SCF_OPTIONLIST) # get scf-options pes = MyPES(atomlist, options, Nst=max(I + 1, 2), **kwds) # create PES atomvec = XYZ.atomlist2vector(atomlist) # convert atomlist to vector # FIND ENERGY MINIMUM # f is the objective function that should be minimized # it returns (f(x), f'(x)) def f(x): if I == 0 and type(pes.tddftb.XmY) != type(None): # only ground state is needed. However, at the start # a single TD-DFT calculation is performed to initialize # all variables (e.g. X-Y), so that the program does not # complain about non-existing variables. enI, gradI = pes.getEnergyAndGradient_S0(x) else: energies, gradI = pes.getEnergiesAndGradient(x, I) enI = energies[I] return enI, gradI minoptions = {'gtol': 1.0e-7, 'norm': 2} # somehow numerical_hessian does not work without doing this mimimization before res = optimize.minimize(f, atomvec, method="CG", jac=True, options=minoptions) # COMPUTE HESSIAN AND VIBRATIONAL MODES # The hessian is calculated by numerical differentiation of the # analytical gradients def grad(x): if I == 0: enI, gradI = pes.getEnergyAndGradient_S0(x) else: energies, gradI = pes.getEnergiesAndGradient(x, I) return gradI print "Computing Hessian" # calculate hessians from gradients hess = HarmonicApproximation.numerical_hessian_G(grad, atomvec) string = "" # create string that is to be written into file for line in hess: for column in line: string += str(column) + " " string = string[:-1] + "\n" with open("hessian.txt", "w") as hessianfile: # write hessian matrix to file hessianfile.write(string) # this would look nicer but is not as exact #hessianfile.write(annotated_hessian(atomlist, hess)) # calculate energy for optimized geometry dftb2 = DFTB2(atomlist, **options) # create dftb object dftb2.setGeometry(atomlist, charge=kwds.get("charge", 0.0)) dftb2.getEnergy(**scf_options) energies = list(dftb2.getEnergies()) # get partial energies if dftb2.long_range_correction == 1: # add long range correction to partial energies energies.append(dftb2.E_HF_x) return str(energies) except: print sys.exc_info() return "error"
def opt(xyzfile, optionfile): """performs an optimization""" outputfile = open("output_dftb.txt", "a") # redirect output to file sys.stdout = outputfile try: I = 0 # index of electronic state (ground state) atomlist = XYZ.read_xyz(xyzfile)[0] # read atomlist kwds = XYZ.extract_keywords_xyz( xyzfile) # read keywords from xyz-file (charge) options = read_options(optionfile) # read options scf_options = extract_options(options, SCF_OPTIONLIST) # get scf-options # optimization (taken from optimize.py) pes = MyPES(atomlist, options, Nst=max(I + 1, 2), **kwds) x0 = XYZ.atomlist2vector(atomlist) #convert geometry to a vector def f(x): save_xyz(x) # also save geometries from line searches if I == 0 and type(pes.tddftb.XmY) != type(None): # only ground state is needed. However, at the start # a single TD-DFT calculation is performed to initialize # all variables (e.g. X-Y), so that the program does not # complain about non-existing variables. enI, gradI = pes.getEnergyAndGradient_S0(x) else: energies, gradI = pes.getEnergiesAndGradient(x, I) enI = energies[I] print "E = %2.7f" % (enI) return enI, gradI xyz_trace = xyzfile.replace(".xyz", "_trace.xyz") # This is a callback function that is executed by numpy for each optimization step. # It appends the current geometry to an xyz-file. def save_xyz(x, mode="a"): atomlist_opt = XYZ.vector2atomlist(x, atomlist) XYZ.write_xyz(xyz_trace, [atomlist_opt], title="charge=%s" % kwds.get("charge", 0), mode=mode) save_xyz(x0, mode="w") # write original geometry Nat = len(atomlist) min_options = {'gtol': 1.0e-7, 'norm': 2} # The "BFGS" method is probably better than "CG", but the line search in BFGS is expensive. res = optimize.minimize(f, x0, method="CG", jac=True, callback=save_xyz, options=min_options) # res = optimize.minimize(f, x0, method="BFGS", jac=True, callback=save_xyz, options=options) xopt = res.x save_xyz(xopt) print "Intermediate geometries written into file {}".format(xyz_trace) # write optimized geometry into file atomlist_opt = XYZ.vector2atomlist(xopt, atomlist) xyz_opt = xyzfile.replace(".xyz", "_opt.xyz") XYZ.write_xyz(xyz_opt, [atomlist_opt], title="charge=%s" % kwds.get("charge", 0), mode="w") # calculate energy for optimized geometry dftb2 = DFTB2(atomlist_opt, **options) # create dftb object dftb2.setGeometry(atomlist_opt, charge=kwds.get("charge", 0.0)) dftb2.getEnergy(**scf_options) energies = list(dftb2.getEnergies()) # get partial energies if dftb2.long_range_correction == 1: # add long range correction to partial energies energies.append(dftb2.E_HF_x) return str(energies) except: print sys.exc_info() return "error"
exit(-1) xyz_in = args[0] xyz_out = args[1] if len(args) < 3: print "possible commands: 'scale', 'dislocate'" exit(-1) cmd = args[2] # the remaining command line arguments depend cmd_args = map(eval, args[3:]) atomlist0 = XYZ.read_xyz(xyz_in)[-1] PG = PerturbedGeometries(atomlist0) kwds = XYZ.extract_keywords_xyz(xyz_in) if cmd == "scale": if len(cmd_args) < 3: print "Arguments for 'scale':" print " smin smax N" exit(-1) geometries = PG.scale(*cmd_args) elif cmd == "dislocate": if len(cmd_args) < 4: print "Arguments for 'dislocate':" print " atom radius nshells N" exit(-1) geometries = PG.dislocate(*cmd_args) else: raise ValueError("Command '%s' not understood" % cmd)