def test_dftb_eigenvector_derivative(): """compare analytical and numerical gradients of MO coefficients and orbital energies""" from DFTB.XYZ import read_xyz, extract_keywords_xyz from DFTB.DFTB2 import DFTB2 from DFTB.Analyse.Cube import CubeExporterEx from DFTB.Molden import MoldenExporter from DFTB import utils from DFTB.LR_TDDFTB import LR_TDDFTB from DFTB.ExcGradients import Gradients import sys import os usage = "Usage: %s <xyz-file>\n" % sys.argv[0] usage += " --help option will give more information\n" parser = utils.OptionParserFuncWrapper([\ DFTB2.__init__, DFTB2.runSCC, \ LR_TDDFTB.getEnergies, LR_TDDFTB.saveAbsorptionSpectrum, LR_TDDFTB.analyseParticleHole, \ LR_TDDFTB.graphical_analysis, \ CubeExporterEx.exportCubes, MoldenExporter.export, \ Gradients.getGradients], \ usage) (options, args) = parser.parse_args(DFTB2.__init__) if len(args) < 1: print(usage) exit(-1) xyz_file = args[0] atomlist = read_xyz(xyz_file)[0] kwds = extract_keywords_xyz(xyz_file) tddftb = LR_TDDFTB(atomlist, **options) (options, args) = parser.parse_args(tddftb.getEnergies) (scf_options, args) = parser.parse_args(tddftb.dftb2.runSCC) options.update(scf_options) tddftb.setGeometry(atomlist, charge=kwds.get("charge", 0.0)) tddftb.getEnergies(**options) grad = Gradients(tddftb) grad.gradient(I=0, save_intermediates_CPKS=1) dE_an, dX_an = grad.getMOgradients() dftb2 = tddftb.dftb2 E = dftb2.getKSEnergies() X = dftb2.getKSCoefficients() dE_num, dX_num = dftb_numerical_mo_gradients(dftb2, atomlist) print("eigenvalues") print(E) print("numerical eigenvalue gradients") print(dE_num) print("analytical eigenvalue gradients") print(dE_an) err_dE = la.norm(dE_num - dE_an) err_dX = la.norm(dX_num - dX_an) assert err_dE < 1.0e-3, "err(dE) = %s" % err_dE
def get_new_charges_dftb((i, symbols, coords)): elements = {"H": 1, "C": 6, "N": 7, "O": 8, "Cl": 17, "Br": 35, "Ru": 44} atomlist = [(elements[sym.capitalize()], tuple(coord)) for sym, coord in zip(symbols, coords)] parser = utils.OptionParserFuncWrapper([DFTB2.DFTB2.__init__], "") (options, args) = parser.parse_args() dftb = DFTB2.DFTB2(atomlist, **options) dftb.setGeometry(atomlist) options = {} dftb.getEnergy(**options) return dftb.dq
def __init__(self, atomlist, options, Nst=2, **kwds): usage = "Type --help to show all options for DFTB" parser = utils.OptionParserFuncWrapper( [DFTB2.__init__, DFTB2.runSCC, LR_TDDFTB.getEnergies], usage) self.options = options td_init_options = extract_options(self.options, TD_INIT_OPTIONLIST) self.atomlist = atomlist self.tddftb = LR_TDDFTB(atomlist, **td_init_options) self.grads = Gradients(self.tddftb) self.tddftb.setGeometry(atomlist, charge=kwds.get("charge", 0.0)) self.scf_options = extract_options(self.options, SCF_OPTIONLIST) self.options = copy(self.scf_options) self.Nst = Nst # # always use iterative diagonalizer for lowest Nst-1 excited states self.options["nstates"] = Nst - 1 # save geometry, orbitals and TD-DFT coefficients from # last calculation self.last_calculation = None # save transition dipoles from last calculation self.tdip_old = None
return None if "-" in qmmm_partitioning: # index list contains ranges such as "9-14" indeces = QMMM.parseAtomTags(inner_indeces) else: indeces = list(eval(qmmm_partitioning)) # start at 0 indeces = [i - 1 for i in indeces] return indeces if __name__ == "__main__": import sys usage = "Usage: python %s <.xyz file> <.dat output file>\n" % sys.argv[0] usage += " The xyz-file should contain the geometries of the two pyrene units.\n" usage += " A table with Rx,Ry and Rz will be written to the output file.\n" usage += " Type --help to see all options.\n" parser = utils.OptionParserFuncWrapper([getQMatoms], usage) (opts, args) = parser.parse_args(getQMatoms) if len(args) < 2: print usage exit(-1) xyz_traj_file = args[0] out_file = args[1] MinimalEnclosingBox.pyrene_dimer_analysis( xyz_traj_file, out_file, qmmm_partitioning=getQMatoms(**opts))
import sys import os.path usage = "Usage: %s\n" % os.path.basename(sys.argv[0]) usage += " creates a tcl script called 'vmd_input.tcl' that allows to visualize the geometries of\n" usage += " a DFTBaby dynamics simulation. The script should be run inside the folder where\n" usage += " the 'dftbaby.cfg' and the 'dynamics.xyz' files are.\n" usage += " To visualize the trajectory, run\n" usage += " \n vmd -e vmd_input.tcl\n\n" # read dftbaby.cfg # This wrapper makes the optional parameters of the python function __init__ visible # as optional command line argument. parser = utils.OptionParserFuncWrapper([DFTB2.__init__, MolecularDynamics.__init__], usage, section_headers=["SurfaceHopping", "DFTBaby"], ignore_unknown_options=True) # extract optional parameters from command line (options,args) = parser.parse_args() # QM/MM partitioning if options.has_key("qmmm_partitioning"): qm_indeces = eval(options["qmmm_partitioning"]) qm_selection = "{" + "or".join(map(str, [" index %d " % (i-1) for i in qm_indeces])) + "}" else: qm_selection = "all" # vmd_commands=r""" # Execute this script as
def test_dftb_charge_derivative(): """compare analytical and numerical gradients of Mulliken charges""" from DFTB.XYZ import read_xyz, extract_keywords_xyz from DFTB.DFTB2 import DFTB2 from DFTB.Analyse.Cube import CubeExporterEx from DFTB.Molden import MoldenExporter from DFTB import utils from DFTB.LR_TDDFTB import LR_TDDFTB from DFTB.ExcGradients import Gradients import sys import os usage = "Usage: %s <xyz-file>\n" % sys.argv[0] usage += " --help option will give more information\n" parser = utils.OptionParserFuncWrapper([\ DFTB2.__init__, DFTB2.runSCC, \ LR_TDDFTB.getEnergies, LR_TDDFTB.saveAbsorptionSpectrum, LR_TDDFTB.analyseParticleHole, \ LR_TDDFTB.graphical_analysis, \ CubeExporterEx.exportCubes, MoldenExporter.export, \ Gradients.getGradients], \ usage) (options, args) = parser.parse_args(DFTB2.__init__) if len(args) < 1: print usage exit(-1) xyz_file = args[0] atomlist = read_xyz(xyz_file)[0] kwds = extract_keywords_xyz(xyz_file) tddftb = LR_TDDFTB(atomlist, **options) (options, args) = parser.parse_args(tddftb.getEnergies) (scf_options, args) = parser.parse_args(tddftb.dftb2.runSCC) options.update(scf_options) tddftb.setGeometry(atomlist, charge=kwds.get("charge", 0.0)) tddftb.getEnergies(**options) grad = Gradients(tddftb) grad.gradient(I=0, save_intermediates_CPKS=1) dQdp_ana = grad.getChargeGradients() dftb2 = tddftb.dftb2 dQdp_num = dftb_numerical_charge_gradients(dftb2, atomlist) print "partial Mulliken charges" print dftb2.getPartialCharges() print "numerical charge gradients" print dQdp_num print "analytical charge gradients" print dQdp_ana print "difference" print dQdp_num - dQdp_ana err_dQ = la.norm(dQdp_num - dQdp_ana) print "err(dQdp) = %s" % err_dQ #assert err_dQ < 1.0e-4, "err(dQdp) = %s" % err_dQ # show timings print T
print >> fh, "# grid for distance d between atomic centers in bohr" print >> fh, "d = \\\n%s" % pp.pformat(self.R) print >> fh, "# repulsive potential in hartree/bohr" print >> fh, "Vrep = \\\n%s" % pp.pformat(self.Vrep) fh.close() if __name__ == "__main__": import sys usage = "Usage: %s <element1> <element2>\n" % sys.argv[0] usage += "element1 and element2 are the elements in the atom pair for which the repulsive potential should be fitted (e.g. h and c)." if len(sys.argv) < 3: print usage exit(-1) parser = utils.OptionParserFuncWrapper(ReppotFitter.fit, usage) (options, args) = parser.parse_args() Z1, Z2 = atomic_number(args[0]), atomic_number(args[1]) Fitter = ReppotFitter(Z1, Z2) print "Files with geometries and forces are read from stdin." print "Each line should be of the form:" print "<identifier> <xyz file with geometry> <xyz file with electronic dftb forces> <xyz file with forces from different method> \\" print " weight=<weight, positive float> max_error=<max. error per atom> \\" print " (active_atoms=<list of atoms IDs, e.g. 0,1,2>)" for line in sys.stdin.readlines(): if line.strip()[0] == "#": # ignore comments continue molname, geom_file, dftb_force_file, force_file, keywords_str = line.strip( ).split(None, 4)
def calculate_charge_derivative(): """compute analytical gradients of Mulliken charges""" # # This long prologue serves for reading all options # from the command line or the dftbaby.cfg file. # The command-line option # # --cpks_solver='direct' or 'iterative' # # determines whether the full CPKS matrix should be constructed ('direct') # or whether the system of linear equations should be solved iteratively using the Krylov # subspace method. # from DFTB.XYZ import read_xyz, extract_keywords_xyz from DFTB.DFTB2 import DFTB2 from DFTB import utils from DFTB.LR_TDDFTB import LR_TDDFTB from DFTB.ExcGradients import Gradients import sys import os usage = "Usage: %s <xyz-file>\n" % sys.argv[0] usage += " --help option will give more information\n" parser = utils.OptionParserFuncWrapper([\ DFTB2.__init__, DFTB2.runSCC, \ LR_TDDFTB.getEnergies, LR_TDDFTB.saveAbsorptionSpectrum, LR_TDDFTB.analyseParticleHole, \ Gradients.getGradients], \ usage) (options, args) = parser.parse_args(DFTB2.__init__) if len(args) < 1: print usage exit(-1) xyz_file = args[0] atomlist = read_xyz(xyz_file)[0] # number of atoms Nat = len(atomlist) kwds = extract_keywords_xyz(xyz_file) tddftb = LR_TDDFTB(atomlist, **options) (options, args) = parser.parse_args(tddftb.getEnergies) (scf_options, args) = parser.parse_args(tddftb.dftb2.runSCC) options.update(scf_options) tddftb.setGeometry(atomlist, charge=kwds.get("charge", 0.0)) tddftb.getEnergies(**options) # # The important part starts here. # grad = Gradients(tddftb) # A CPKS calculation has to be preceeded by a gradient calculation. # The option `save_intermediates_CPKS=1` tells the program to save intermediate # variables that are needed later during the CPKS calculation. grad.gradient(I=0, save_intermediates_CPKS=1) # This runs a CPKS calculation and computes the gradients of the charges dQdp = grad.getChargeGradients() # The gradient of the charge on atom B w/r/t the position of atom A is # d(Q_B)/dR_A = dQdp[3*A:3*(A+1), B] A = 0 # first atom B = Nat - 1 # last atom print "Gradient of Mulliken charge on atom A=%d w/r/t nucleus B=%d d(Q_B)/dR_A = %s" \ % (A, B, dQdp[3*A:3*(A+1), B])
=========== scale_min: scale factor for smallest structure scale_max: scale factor for largest structure Nscale: number of points in the interval [scale_min, scale_max] """ geometry = XYZ.read_xyz(self.xyz_in_file)[0] scaled_geoms = [] for s in linspace(scale_min, scale_max, Nscale): scaled_atomlist = [] for (Zi, (xi, yi, zi)) in geometry: scaled_atomlist.append((Zi, (xi * s, yi * s, zi * s))) scaled_geoms.append(scaled_atomlist) XYZ.write_xyz(self.xyz_scaled_file, scaled_geoms, title="scaled geometries") if __name__ == "__main__": import sys usage = "python %s <geometry .xyz-file> <scaled geometries .xyz-file>\n\n" % sys.argv[ 0] usage += "generate different geometries by scaling the position vector of each atom by a constant factor." if len(sys.argv) < 3: print usage exit(-1) SG = ScaledGeometries(sys.argv[1], sys.argv[2]) parser = utils.OptionParserFuncWrapper(SG.generate_scaled_geometries, usage) (options, args) = parser.parse_args() SG.generate_scaled_geometries(**options)