Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
 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))
Exemple #5
0
    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
Exemple #6
0
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
Exemple #7
0
        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])
Exemple #9
0
        ===========
        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)