示例#1
0
def rhf(atoms, **kwargs):
    """\
    rhf(atoms,**kwargs) - Closed-shell HF driving routine
    
    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS for accelerated convergence (default)
                  False   No convergence acceleration
    ETemp         False   Use ETemp value for finite temperature DFT (default)
                  float   Use (float) for the electron temperature
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not none, the guess orbitals
    """
    ConvCriteria = kwargs.get('ConvCriteria', settings.ConvergenceCriteria)
    MaxIter = kwargs.get('MaxIter', settings.MaxIter)
    DoAveraging = kwargs.get('DoAveraging', settings.Averaging)
    ETemp = kwargs.get('ETemp', settings.ElectronTemperature)

    logger.info("RHF calculation on %s" % atoms.name)

    bfs = getbasis(atoms, **kwargs)

    nclosed, nopen = atoms.get_closedopen()
    nocc = nclosed
    assert (nopen == 0), "SCF currently only works for closed-shell systems"

    logger.info("Nbf = %d" % len(bfs))
    logger.info("Nclosed = %d" % nclosed)

    S, h, Ints = getints(bfs, atoms, **kwargs)
    nel = atoms.get_nel()

    orbs = kwargs.get('orbs')
    if orbs is None: orbe, orbs = geigh(h, S)

    enuke = atoms.get_enuke()
    eold = 0.

    if DoAveraging:
        logger.info("Using DIIS averaging")
        avg = DIIS(S)
    logging.debug("Optimization of HF orbitals")
    for i in xrange(MaxIter):
        if ETemp:
            efermi = get_efermi(nel, orbe, ETemp)
            occs = get_fermi_occs(efermi, orbe, ETemp)
            D = mkdens_occs(orbs, occs)
            entropy = get_entropy(occs, ETemp)
        else:
            D = mkdens(orbs, 0, nocc)
        G = get2JmK(Ints, D)
        F = h + G
        if DoAveraging: F = avg.getF(F, D)
        orbe, orbs = geigh(F, S)
        energy = get_energy(h, F, D, enuke)
        if ETemp:
            energy += entropy
        logging.debug("%d %f" % (i, energy))
        if abs(energy - eold) < ConvCriteria: break
        logger.info("Iteration: %d    Energy: %f    EnergyVar: %f" %
                    (i, energy, abs(energy - eold)))
        eold = energy
    if i < MaxIter:
        logger.info("PyQuante converged in %d iterations" % i)
    else:
        logger.warning("PyQuante failed to converge after %d iterations" %
                       MaxIter)
    logger.info("Final HF energy for system %s is %f" % (atoms.name, energy))
    return energy, orbe, orbs
示例#2
0
def dft_fixed_occ(atoms, occs, **kwargs):
    """\
    dft(atoms,**kwargs) - DFT driving routine

    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    verbose       False   Output terse information to stdout (default)
                  True    Print out additional information 
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS for accelerated convergence (default)
                  False   No convergence acceleration
    ETemp         False   Use ETemp value for finite temperature DFT (default)
                  float   Use (float) for the electron temperature
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not none, the guess orbitals
    functional    SVWN    Use the SVWN (LDA) DFT functional (default)
                  S0      Use the Slater Xalpha DFT functional
                  BLYP    Use the BLYP GGA DFT functional
                  PBE     Use the PBE DFT functional
    grid_nrad     32      Number of radial shells per atom
    grid_fineness 1       Radial shell fineness. 0->coarse, 1->medium, 2->fine
    spin_type     A       Average occupation method for open shell (default)
                  R       Restricted open shell (not implemented yet)
                  U       Unrestricted open shell (aka spin-polarized dft)
                          Only A works now. Stay tuned.
    """
    verbose = kwargs.get('verbose', False)
    ConvCriteria = kwargs.get('ConvCriteria', 1e-4)
    MaxIter = kwargs.get('MaxIter', 20)
    DoAveraging = kwargs.get('DoAveraging', True)
    ETemp = kwargs.get('ETemp', False)
    functional = kwargs.get('functional', 'SVWN')
    kwargs['do_grad_dens'] = need_gradients[functional]

    bfs = kwargs.get('bfs', None)
    if not bfs:
        basis_data = kwargs.get('basis_data', None)
        bfs = getbasis(atoms, basis_data)

    integrals = kwargs.get('integrals', None)
    if integrals:
        S, h, Ints = integrals
    else:
        S, h, Ints = getints(bfs, atoms)

    nel = atoms.get_nel()
    enuke = atoms.get_enuke()

    # default medium mesh
    grid_nrad = kwargs.get('grid_nrad', 32)
    grid_fineness = kwargs.get('grid_fineness', 1)

    gr = MolecularGrid(atoms, grid_nrad, grid_fineness, **kwargs)
    gr.set_bf_amps(bfs)

    # It would be nice to have a more intelligent treatment of the guess
    # so that I could pass in a density rather than a set of orbs.
    orbs = kwargs.get('orbs', None)
    if orbs is None: orbe, orbs = geigh(h, S)

    nclosed, nopen = atoms.get_closedopen()

    if verbose:
        print "DFT calculation on %s using functional %s" % (atoms.name,
                                                             functional)
        print "Nbf = %d" % len(bfs)
        print "Nclosed = %d" % nclosed
        print "Nopen = %d" % nclosed
        if nopen: print "Using spin-averaged dft for open shell calculation"

    eold = 0.
    if DoAveraging:
        print "Using DIIS averaging"
        avg = DIIS(S)

    # Converge the LDA density for the system:
    if verbose: print "Optimization of DFT density"
    for i in xrange(MaxIter):
        #print "SCF Iteration:",i,"Starting Energy:",eold
        #save the starting orbitals
        oldorbs = orbs
        if ETemp:
            efermi = get_efermi(nel, orbe, ETemp)
            occs = get_fermi_occs(efermi, orbe, ETemp)
            D = mkdens_occs(orbs, occs)
            entropy = get_entropy(occs, ETemp)
        else:
            D = mk_auger_dens(orbs, occs)
            #D = mkdens_spinavg(orbs,nclosed,nopen)

        gr.setdens(D)

        J = getJ(Ints, D)

        Exc, XC = getXC(gr, nel, **kwargs)

        F = h + 2 * J + XC
        if DoAveraging: F = avg.getF(F, D)

        orbe, orbs = geigh(F, S)
        #pad_out(orbs)
        #save the new eigenstates of the fock operator F
        neworbs = orbs
        #send oldorbs and neworbs to get biorthogonalized method
        #orbs = biorthog(neworbs, oldorbs, S, nel)

        Ej = 2 * trace2(D, J)
        Eone = 2 * trace2(D, h)
        energy = Eone + Ej + Exc + enuke
        print i + 1, "   ", energy, "    ", Ej, "  ", Exc, " ", enuke
        if ETemp: energy += entropy
        if verbose:
            print "%d %10.4f %10.4f %10.4f %10.4f %10.4f" % (i, energy, Eone,
                                                             Ej, Exc, enuke)
        if abs(energy - eold) < ConvCriteria: break
        eold = energy

    print "Final %s energy for system %s is %f" % (functional, atoms.name,
                                                   energy)
    return energy, orbe, orbs