Beispiel #1
0
def run_v2rdm_casscf(name, **kwargs):
    r"""Function encoding sequence of PSI module and plugin calls so that
    v2rdm_casscf can be called via :py:func:`~driver.energy`. For post-scf plugins.

    >>> energy('v2rdm_casscf')

    """

    lowername = name.lower()
    kwargs = p4util.kwargs_lower(kwargs)

    optstash = p4util.OptionsState(
        ['SCF', 'DF_INTS_IO'])

    psi4.set_local_option('SCF', 'DF_INTS_IO', 'SAVE')

    # Your plugin's psi4 run sequence goes here
    scf_wfn = scf_helper(name, **kwargs)

    # if restarting from a checkpoint file, this file
    # needs to be in scratch with the correct name
    filename = psi4.get_option("V2RDM_CASSCF","RESTART_FROM_CHECKPOINT_FILE")

    # todo PSIF_V2RDM_CHECKPOINT should be definied in psifiles.h
    if ( filename != "" ):
        molname = psi4.wavefunction().molecule().name()
        p4util.copy_file_to_scratch(filename,'psi',molname,269,False)

    returnvalue = psi4.plugin('v2rdm_casscf.so',scf_wfn)

    #psi4.set_variable('CURRENT ENERGY', returnvalue)

    return psi4.get_variable('CURRENT ENERGY')
Beispiel #2
0
def run_v2rdm_casscf(name, **kwargs):
    r"""Function encoding sequence of PSI module and plugin calls so that
    v2rdm_casscf can be called via :py:func:`~driver.energy`. For post-scf plugins.

    >>> energy('v2rdm_casscf')

    """

    lowername = name.lower()
    kwargs = p4util.kwargs_lower(kwargs)

    optstash = p4util.OptionsState(['SCF', 'DF_INTS_IO'])

    psi4.set_local_option('SCF', 'DF_INTS_IO', 'SAVE')

    # Your plugin's psi4 run sequence goes here
    scf_wfn = scf_helper(name, **kwargs)

    # if restarting from a checkpoint file, this file
    # needs to be in scratch with the correct name
    filename = psi4.get_option("V2RDM_CASSCF", "RESTART_FROM_CHECKPOINT_FILE")

    # todo PSIF_V2RDM_CHECKPOINT should be definied in psifiles.h
    if (filename != ""):
        molname = psi4.wavefunction().molecule().name()
        p4util.copy_file_to_scratch(filename, 'psi', molname, 269, False)

    returnvalue = psi4.plugin('v2rdm_casscf.so', scf_wfn)

    #psi4.set_variable('CURRENT ENERGY', returnvalue)

    return psi4.get_variable('CURRENT ENERGY')
Beispiel #3
0
    def fitGeneral(self):
        """Function to perform a general fit of diffuse charges
        to wavefunction density.

        """
        psi4.print_out("    => Diffuse Charge Fitting (Determines da) <=\n\n")
        self.wfn = psi4.wavefunction()
        self.Da = self.wfn.Da()
        self.basis = self.wfn.basisset()
        parser = psi4.Gaussian94BasisSetParser()
        self.ribasis = psi4.BasisSet.construct(parser, self.molecule, "DF_BASIS_SCF")

        fitter = psi4.DFChargeFitter()
        fitter.setPrimary(self.basis)
        fitter.setAuxiliary(self.ribasis)
        fitter.setD(self.Da)
        self.da = fitter.fit()
        self.da.scale(2.0)
Beispiel #4
0
    def fitGeneral(self):
        """Function to perform a general fit of diffuse charges
        to wavefunction density.

        """
        psi4.print_out("    => Diffuse Charge Fitting (Determines da) <=\n\n")
        self.wfn = psi4.wavefunction()
        self.Da = self.wfn.Da()
        self.basis = self.wfn.basisset()
        parser = psi4.Gaussian94BasisSetParser()
        self.ribasis = psi4.BasisSet.construct(parser, self.molecule,
                                               "DF_BASIS_SCF")

        fitter = psi4.DFChargeFitter()
        fitter.setPrimary(self.basis)
        fitter.setAuxiliary(self.ribasis)
        fitter.setD(self.Da)
        self.da = fitter.fit()
        self.da.scale(2.0)
Beispiel #5
0
def run_v2rdm_casscf(name, **kwargs):
    r"""Function encoding sequence of PSI module and plugin calls so that
    v2rdm_casscf can be called via :py:func:`~driver.energy`. For post-scf plugins.

    >>> energy('v2rdm_casscf')

    """

    lowername = name.lower()
    kwargs = p4util.kwargs_lower(kwargs)

    optstash = p4util.OptionsState(['SCF', 'DF_INTS_IO'])

    psi4.core.set_local_option('SCF', 'DF_INTS_IO', 'SAVE')

    # Your plugin's psi4 run sequence goes here
    ref_wfn = kwargs.get('ref_wfn', None)
    if ref_wfn is None:
        ref_wfn = psi4.driver.scf_helper(name, **kwargs)

    # if restarting from a checkpoint file, this file
    # needs to be in scratch with the correct name
    filename = psi4.core.get_option("V2RDM_CASSCF",
                                    "RESTART_FROM_CHECKPOINT_FILE")

    # todo PSIF_V2RDM_CHECKPOINT should be definied in psifiles.h
    if (filename != "" and psi4.core.get_global_option('DERTYPE') != 'FIRST'):
        molname = psi4.wavefunction().molecule().name()
        p4util.copy_file_to_scratch(filename, 'psi', molname, 269, False)

    # Ensure IWL files have been written when not using DF/CD
    scf_type = psi4.core.get_option('SCF', 'SCF_TYPE')
    if (scf_type == 'PK' or scf_type == 'DIRECT'):
        proc_util.check_iwl_file_from_scf_type(
            psi4.core.get_option('SCF', 'SCF_TYPE'), ref_wfn)

    returnvalue = psi4.core.plugin('v2rdm_casscf.so', ref_wfn)

    optstash.restore()

    return returnvalue
Beispiel #6
0
def ip_fitting(mol, omega_l, omega_r, **kwargs):
    kwargs = p4util.kwargs_lower(kwargs)

    # By default, zero the omega to 3 digits
    omega_tol = 1.0E-3
    if (kwargs.has_key('omega_tolerance')):
        omega_tol = kwargs['omega_tolerance']

    # By default, do up to twenty iterations
    maxiter = 20
    if (kwargs.has_key('maxiter')):
        maxiter = kwargs['maxiter']

    # By default, do not read previous 180 orbitals file
    read = False
    read180 = ''
    if (kwargs.has_key('read')):
        read = True
        read180 = kwargs['read']

    # The molecule is required, and should be the neutral species
    mol.update_geometry()
    activate(mol)
    charge0 = mol.molecular_charge()
    mult0 = mol.multiplicity()

    # How many electrons are there?
    N = 0
    for A in range(mol.natom()):
        N += mol.Z(A)
    N -= charge0
    N = int(N)
    Nb = int((N - mult0 + 1) / 2)
    Na = int(N - Nb)

    # Work in the ot namespace for this procedure
    psi4.IO.set_default_namespace("ot")

    # Burn in to determine orbital eigenvalues
    if (read):
        psi4.set_global_option("GUESS", "READ")
        copy_file_to_scratch(read180, 'psi', 'ot', 180)
    old_guess = psi4.get_global_option("GUESS")
    psi4.set_global_option("DF_INTS_IO", "SAVE")
    psi4.print_out('\n\t==> IP Fitting SCF: Burn-in <==\n')
    energy('scf')
    psi4.set_global_option("DF_INTS_IO", "LOAD")

    # Determine H**O, to determine mult1
    ref = psi4.wavefunction()
    eps_a = ref.epsilon_a()
    eps_b = ref.epsilon_b()
    if (Na == Nb):
        H**O = -Nb
    elif (Nb == 0):
        H**O = Na
    else:
        E_a = eps_a[int(Na - 1)]
        E_b = eps_b[int(Nb - 1)]
        if (E_a >= E_b):
            H**O = Na
        else:
            H**O = -Nb

    Na1 = Na
    Nb1 = Nb
    if (H**O > 0):
        Na1 = Na1 - 1
    else:
        Nb1 = Nb1 - 1

    charge1 = charge0 + 1
    mult1 = Na1 - Nb1 + 1

    omegas = []
    E0s = []
    E1s = []
    kIPs = []
    IPs = []
    types = []

    # Right endpoint
    psi4.set_global_option('DFT_OMEGA', omega_r)

    # Neutral
    if (read):
        psi4.set_global_option("GUESS", "READ")
        p4util.copy_file_to_scratch(read180, 'psi', 'ot', 180)

    mol.set_molecular_charge(charge0)
    mol.set_multiplicity(mult0)
    psi4.print_out('\n\t==> IP Fitting SCF: Neutral, Right Endpoint <==\n')
    E0r = energy('scf')
    ref = psi4.wavefunction()
    eps_a = ref.epsilon_a()
    eps_b = ref.epsilon_b()
    E_HOMO = 0.0
    if (Nb == 0):
        E_HOMO = eps_a[int(Na - 1)]
    else:
        E_a = eps_a[int(Na - 1)]
        E_b = eps_b[int(Nb - 1)]
        if (E_a >= E_b):
            E_HOMO = E_a
        else:
            E_HOMO = E_b
    E_HOMOr = E_HOMO
    psi4.IO.change_file_namespace(180, "ot", "neutral")

    # Cation
    if (read):
        psi4.set_global_option("GUESS", "READ")
        p4util.copy_file_to_scratch(read180, 'psi', 'ot', 180)

    mol.set_molecular_charge(charge1)
    mol.set_multiplicity(mult1)
    psi4.print_out('\n\t==> IP Fitting SCF: Cation, Right Endpoint <==\n')
    E1r = energy('scf')
    psi4.IO.change_file_namespace(180, "ot", "cation")

    IPr = E1r - E0r
    kIPr = -E_HOMOr
    delta_r = IPr - kIPr

    if (IPr > kIPr):
        psi4.print_out(
            '\n***IP Fitting Error: Right Omega limit should have kIP > IP')
        sys.exit(1)

    omegas.append(omega_r)
    types.append('Right Limit')
    E0s.append(E0r)
    E1s.append(E1r)
    IPs.append(IPr)
    kIPs.append(kIPr)

    # Use previous orbitals from here out
    psi4.set_global_option("GUESS", "READ")

    # Left endpoint
    psi4.set_global_option('DFT_OMEGA', omega_l)

    # Neutral
    psi4.IO.change_file_namespace(180, "neutral", "ot")
    mol.set_molecular_charge(charge0)
    mol.set_multiplicity(mult0)
    psi4.print_out('\n\t==> IP Fitting SCF: Neutral, Left Endpoint <==\n')
    E0l = energy('scf')
    ref = psi4.wavefunction()
    eps_a = ref.epsilon_a()
    eps_b = ref.epsilon_b()
    E_HOMO = 0.0
    if (Nb == 0):
        E_HOMO = eps_a[int(Na - 1)]
    else:
        E_a = eps_a[int(Na - 1)]
        E_b = eps_b[int(Nb - 1)]
        if (E_a >= E_b):
            E_HOMO = E_a
        else:
            E_HOMO = E_b
    E_HOMOl = E_HOMO
    psi4.IO.change_file_namespace(180, "ot", "neutral")

    # Cation
    psi4.IO.change_file_namespace(180, "cation", "ot")
    mol.set_molecular_charge(charge1)
    mol.set_multiplicity(mult1)
    psi4.print_out('\n\t==> IP Fitting SCF: Cation, Left Endpoint <==\n')
    E1l = energy('scf')
    psi4.IO.change_file_namespace(180, "ot", "cation")

    IPl = E1l - E0l
    kIPl = -E_HOMOl
    delta_l = IPl - kIPl

    if (IPl < kIPl):
        psi4.print_out(
            '\n***IP Fitting Error: Left Omega limit should have kIP < IP')
        sys.exit(1)

    omegas.append(omega_l)
    types.append('Left Limit')
    E0s.append(E0l)
    E1s.append(E1l)
    IPs.append(IPl)
    kIPs.append(kIPl)

    converged = False
    repeat_l = 0
    repeat_r = 0
    step = 0
    while True:

        step = step + 1

        # Regula Falsi (modified)
        if (repeat_l > 1):
            delta_l = delta_l / 2.0
        if (repeat_r > 1):
            delta_r = delta_r / 2.0
        omega = -(omega_r - omega_l) / (delta_r - delta_l) * delta_l + omega_l
        psi4.set_global_option('DFT_OMEGA', omega)

        # Neutral
        psi4.IO.change_file_namespace(180, "neutral", "ot")
        mol.set_molecular_charge(charge0)
        mol.set_multiplicity(mult0)
        psi4.print_out(
            '\n\t==> IP Fitting SCF: Neutral, Omega = %11.3E <==\n' % omega)
        E0 = energy('scf')
        ref = psi4.wavefunction()
        eps_a = ref.epsilon_a()
        eps_b = ref.epsilon_b()
        E_HOMO = 0.0
        if (Nb == 0):
            E_HOMO = eps_a[int(Na - 1)]
        else:
            E_a = eps_a[int(Na - 1)]
            E_b = eps_b[int(Nb - 1)]
            if (E_a >= E_b):
                E_HOMO = E_a
            else:
                E_HOMO = E_b
        psi4.IO.change_file_namespace(180, "ot", "neutral")

        # Cation
        psi4.IO.change_file_namespace(180, "cation", "ot")
        mol.set_molecular_charge(charge1)
        mol.set_multiplicity(mult1)
        psi4.print_out('\n\t==> IP Fitting SCF: Cation, Omega = %11.3E <==\n' %
                       omega)
        E1 = energy('scf')
        psi4.IO.change_file_namespace(180, "ot", "cation")

        IP = E1 - E0
        kIP = -E_HOMO
        delta = IP - kIP

        if (kIP > IP):
            omega_r = omega
            E0r = E0
            E1r = E1
            IPr = IP
            kIPr = kIP
            delta_r = delta
            repeat_r = 0
            repeat_l = repeat_l + 1
        else:
            omega_l = omega
            E0l = E0
            E1l = E1
            IPl = IP
            kIPl = kIP
            delta_l = delta
            repeat_l = 0
            repeat_r = repeat_r + 1

        omegas.append(omega)
        types.append('Regula-Falsi')
        E0s.append(E0)
        E1s.append(E1)
        IPs.append(IP)
        kIPs.append(kIP)

        # Termination
        if (abs(omega_l - omega_r) < omega_tol or step > maxiter):
            converged = True
            break

    psi4.IO.set_default_namespace("")

    psi4.print_out('\n\t==> IP Fitting Results <==\n\n')

    psi4.print_out('\t => Occupation Determination <= \n\n')
    psi4.print_out('\t          %6s %6s %6s %6s %6s %6s\n' %
                   ('N', 'Na', 'Nb', 'Charge', 'Mult', 'H**O'))
    psi4.print_out('\t Neutral: %6d %6d %6d %6d %6d %6d\n' %
                   (N, Na, Nb, charge0, mult0, H**O))
    psi4.print_out('\t Cation:  %6d %6d %6d %6d %6d\n\n' %
                   (N - 1, Na1, Nb1, charge1, mult1))

    psi4.print_out('\t => Regula Falsi Iterations <=\n\n')
    psi4.print_out('\t%3s %11s %14s %14s %14s %s\n' %
                   ('N', 'Omega', 'IP', 'kIP', 'Delta', 'Type'))
    for k in range(len(omegas)):
        psi4.print_out(
            '\t%3d %11.3E %14.6E %14.6E %14.6E %s\n' %
            (k + 1, omegas[k], IPs[k], kIPs[k], IPs[k] - kIPs[k], types[k]))
    if (converged):
        psi4.print_out('\n\tIP Fitting Converged\n')
        psi4.print_out('\tFinal omega = %14.6E\n' % ((omega_l + omega_r) / 2))
        psi4.print_out(
            '\n\t"M,I. does the dying. Fleet just does the flying."\n')
        psi4.print_out('\t\t\t-Starship Troopers\n')

    else:
        psi4.print_out('\n\tIP Fitting did not converge!\n')

    psi4.set_global_option("DF_INTS_IO", "NONE")
    psi4.set_global_option("GUESS", old_guess)
Beispiel #7
0
def frac_traverse(mol, **kwargs):
    kwargs = p4util.kwargs_lower(kwargs)

    # The molecule is required, and should be the neutral species
    mol.update_geometry()
    activate(mol)
    charge0 = mol.molecular_charge()
    mult0 = mol.multiplicity()

    chargep = charge0 + 1
    chargem = charge0 - 1

    # By default, the multiplicity of the cation/anion are mult0 + 1
    # These are overridden with the cation_mult and anion_mult kwargs
    multp = mult0 + 1
    multm = mult0 + 1
    if kwargs.has_key('cation_mult'):
        multp = kwargs['cation_mult']
    if kwargs.has_key('anion_mult'):
        multm = kwargs['anion_mult']

    # By default, we start the frac procedure on the 25th iteration
    # when not reading a previous guess
    frac_start = 25
    if kwargs.has_key('frac_start'):
        frac_start = kwargs['frac_start']

    # By default, we occupy by tenths of electrons
    LUMO_occs = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]
    HOMO_occs = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]
    if kwargs.has_key('HOMO_occs'):
        HOMO_occs = kwargs['HOMO_occs']
    if kwargs.has_key('LUMO_occs'):
        LUMO_occs = kwargs['LUMO_occs']

    # By default, H**O and LUMO are both in alpha
    Z = 0
    for A in range(mol.natom()):
        Z += mol.Z(A)
    Z -= charge0
    if (Z % 2):
        H**O = Z / 2 + 1
    else:
        H**O = Z / 2
    LUMO = H**O + 1
    if kwargs.has_key('H**O'):
        H**O = kwargs['H**O']
    if kwargs.has_key('LUMO'):
        LUMO = kwargs['LUMO']

    # By default, DIIS in FRAC (1.0 occupation is always DIIS'd)
    frac_diis = True
    if kwargs.has_key('frac_diis'):
        frac_diis = kwargs['frac_diis']

    # By default, use the neutral orbitals as a guess for the anion
    neutral_guess = True
    if kwargs.has_key('neutral_guess'):
        neutral_guess = kwargs['neutral_guess']

    # By default, burn-in with UHF first, if UKS
    hf_guess = False
    if psi4.get_global_option('REFERENCE') == 'UKS':
        hf_guess = True
        if kwargs.has_key('hf_guess'):
            hf_guess = kwargs['hf_guess']

    # By default, re-guess at each N
    continuous_guess = False
    if kwargs.has_key('continuous_guess'):
        continuous_guess = kwargs['continuous_guess']

    # By default, drop the files to the molecule's name
    root = mol.name()
    if kwargs.has_key('filename'):
        root = kwargs['filename']
    traverse_filename = root + '.traverse.dat'
    # => Traverse <= #
    occs = []
    energies = []
    potentials = []
    convs = []

    # => Run the neutral for its orbitals, if requested <= #

    old_df_ints_io = psi4.get_global_option("DF_INTS_IO")
    psi4.set_global_option("DF_INTS_IO", "SAVE")

    old_guess = psi4.get_global_option("GUESS")
    if (neutral_guess):
        if (hf_guess):
            psi4.set_global_option("REFERENCE", "UHF")
        energy('scf')
        psi4.set_global_option("GUESS", "READ")
        psi4.set_global_option("DF_INTS_IO", "LOAD")

    # => Run the anion first <= #

    mol.set_molecular_charge(chargem)
    mol.set_multiplicity(multm)

    # => Burn the anion in with hf, if requested <= #
    if (hf_guess):
        psi4.set_global_option("REFERENCE", "UHF")
        energy('scf')
        psi4.set_global_option("REFERENCE", "UKS")
        psi4.set_global_option("GUESS", "READ")
        psi4.set_global_option("DF_INTS_IO", "SAVE")

    psi4.set_global_option("FRAC_START", frac_start)
    psi4.set_global_option("FRAC_RENORMALIZE", True)
    psi4.set_global_option("FRAC_LOAD", False)

    for occ in LUMO_occs:

        psi4.set_global_option("FRAC_OCC", [LUMO])
        psi4.set_global_option("FRAC_VAL", [occ])

        E = energy('scf')
        C = 1
        if (E == 0.0):
            E = psi4.get_variable('SCF ITERATION ENERGY')
            C = 0

        if (LUMO > 0):
            ref = psi4.wavefunction()
            eps = ref.epsilon_a()
            potentials.append(eps[int(LUMO) - 1])
        else:
            ref = psi4.wavefunction()
            eps = ref.epsilon_b()
            potentials.append(eps[-int(LUMO) - 1])

        occs.append(occ)
        energies.append(E)
        convs.append(C)

        psi4.set_global_option("FRAC_START", 2)
        psi4.set_global_option("FRAC_LOAD", True)
        psi4.set_global_option("GUESS", "READ")
        psi4.set_global_option("FRAC_DIIS", frac_diis)
        psi4.set_global_option("DF_INTS_IO", "LOAD")

    # => Run the neutral next <= #

    mol.set_molecular_charge(charge0)
    mol.set_multiplicity(mult0)

    # Burn the neutral in with hf, if requested <= #

    if (not continuous_guess):
        psi4.set_global_option("GUESS", old_guess)
        if (hf_guess):
            psi4.set_global_option("FRAC_START", 0)
            psi4.set_global_option("REFERENCE", "UHF")
            energy('scf')
            psi4.set_global_option("REFERENCE", "UKS")
            psi4.set_global_option("GUESS", "READ")
        psi4.set_global_option("FRAC_LOAD", False)

    psi4.set_global_option("FRAC_START", frac_start)
    psi4.set_global_option("FRAC_RENORMALIZE", True)

    for occ in HOMO_occs:

        psi4.set_global_option("FRAC_OCC", [H**O])
        psi4.set_global_option("FRAC_VAL", [occ])

        E = energy('scf')
        C = 1
        if (E == 0.0):
            E = psi4.get_variable('SCF ITERATION ENERGY')
            C = 0

        if (LUMO > 0):
            ref = psi4.wavefunction()
            eps = ref.epsilon_a()
            potentials.append(eps[int(H**O) - 1])
        else:
            ref = psi4.wavefunction()
            eps = ref.epsilon_b()
            potentials.append(eps[-int(H**O) - 1])

        occs.append(occ - 1.0)
        energies.append(E)
        convs.append(C)

        psi4.set_global_option("FRAC_START", 2)
        psi4.set_global_option("FRAC_LOAD", True)
        psi4.set_global_option("GUESS", "READ")
        psi4.set_global_option("FRAC_DIIS", frac_diis)
        psi4.set_global_option("DF_INTS_IO", "LOAD")

    psi4.set_global_option("DF_INTS_IO", old_df_ints_io)

    # => Print the results out <= #
    E = {}
    psi4.print_out('\n    ==> Fractional Occupation Traverse Results <==\n\n')
    psi4.print_out('\t%-11s %-24s %-24s %11s\n' %
                   ('N', 'Energy', 'H**O Energy', 'Converged'))
    for k in range(len(occs)):
        psi4.print_out('\t%11.3E %24.16E %24.16E %11d\n' %
                       (occs[k], energies[k], potentials[k], convs[k]))
        E[occs[k]] = energies[k]

    psi4.print_out('\n\t"You trying to be a hero Watkins?"\n')
    psi4.print_out('\t"Just trying to kill some bugs sir!"\n')
    psi4.print_out('\t\t\t-Starship Troopers\n')

    # Drop the files out
    fh = open(traverse_filename, 'w')
    fh.write('\t%-11s %-24s %-24s %11s\n' %
             ('N', 'Energy', 'H**O Energy', 'Converged'))
    for k in range(len(occs)):
        fh.write('\t%11.3E %24.16E %24.16E %11d\n' %
                 (occs[k], energies[k], potentials[k], convs[k]))
    fh.close()

    return E
Beispiel #8
0
def frac_nuke(mol, **kwargs):
    kwargs = p4util.kwargs_lower(kwargs)

    # The molecule is required, and should be the neutral species
    mol.update_geometry()
    activate(mol)
    charge0 = mol.molecular_charge()
    mult0 = mol.multiplicity()

    # By default, we start the frac procedure on the 25th iteration
    # when not reading a previous guess
    frac_start = 25
    if kwargs.has_key('frac_start'):
        frac_start = kwargs['frac_start']

    # By default, we occupy by tenths of electrons
    foccs = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]
    if kwargs.has_key('foccs'):
        foccs = kwargs['foccs']

    # By default, H**O and LUMO are both in alpha
    N = 0
    for A in range(mol.natom()):
        N += mol.Z(A)
    N -= charge0
    N = int(N)
    Nb = int((N - mult0 + 1) / 2)
    Na = int(N - Nb)

    charge = charge0
    mult = mult0

    # By default, nuke all the electrons
    Nmin = 0
    if (kwargs.has_key('nmax')):
        Nmin = N - int(kwargs['nmax'])

    # By default, DIIS in FRAC (1.0 occupation is always DIIS'd)
    frac_diis = True
    if kwargs.has_key('frac_diis'):
        frac_diis = kwargs['frac_diis']

    # By default, drop the files to the molecule's name
    root = mol.name()
    if kwargs.has_key('filename'):
        root = kwargs['filename']
    traverse_filename = root + '.traverse.dat'
    stats_filename = root + '.stats.dat'

    # => Traverse <= #
    psi4.set_global_option("DF_INTS_IO", "SAVE")

    Ns = []
    energies = []
    potentials = []
    convs = []
    stats = []

    # Run one SCF to burn things in
    energy('scf')

    # Determine H**O
    ref = psi4.wavefunction()
    eps_a = ref.epsilon_a()
    eps_b = ref.epsilon_b()
    if (Na == Nb):
        H**O = -Nb
    elif (Nb == 0):
        H**O = Na
    else:
        E_a = eps_a[int(Na - 1)]
        E_b = eps_b[int(Nb - 1)]
        if (E_a >= E_b):
            H**O = Na
        else:
            H**O = -Nb

    stats.append('\t%6d %6d %6d %6d %6d %6d\n' %
                 (N, Na, Nb, charge, mult, H**O))

    if (H**O > 0):
        Na = Na - 1
    else:
        Nb = Nb - 1
    charge = charge + 1
    mult = Na - Nb + 1

    psi4.set_global_option("DF_INTS_IO", "LOAD")
    psi4.set_global_option("FRAC_START", frac_start)
    psi4.set_global_option("FRAC_RENORMALIZE", True)

    # Nuke 'em Rico!
    for Nintegral in range(N, Nmin, -1):

        # Nuke the current H**O
        for occ in foccs:

            psi4.set_global_option("FRAC_OCC", [H**O])
            psi4.set_global_option("FRAC_VAL", [occ])

            E = energy('scf')
            C = 1
            if (E == 0.0):
                E = psi4.get_variable('SCF ITERATION ENERGY')
                C = 0

            if (H**O > 0):
                ref = psi4.wavefunction()
                eps = ref.epsilon_a()
                potentials.append(eps[H**O - 1])
            else:
                ref = psi4.wavefunction()
                eps = ref.epsilon_b()
                potentials.append(eps[-H**O - 1])

            Ns.append(Nintegral + occ - 1.0)
            energies.append(E)
            convs.append(C)

            psi4.set_global_option("FRAC_START", 2)
            psi4.set_global_option("FRAC_LOAD", True)
            psi4.set_global_option("FRAC_DIIS", frac_diis)
            psi4.set_global_option("GUESS", "READ")

        # Set the next charge/mult
        mol.set_molecular_charge(charge)
        mol.set_multiplicity(mult)

        # Determine H**O
        ref = psi4.wavefunction()
        eps_a = ref.epsilon_a()
        eps_b = ref.epsilon_b()
        if (Na == Nb):
            H**O = -Nb
        elif (Nb == 0):
            H**O = Na
        else:
            E_a = eps_a[int(Na - 1)]
            E_b = eps_b[int(Nb - 1)]
            if (E_a >= E_b):
                H**O = Na
            else:
                H**O = -Nb

        stats.append('\t%6d %6d %6d %6d %6d %6d\n' %
                     (Nintegral - 1, Na, Nb, charge, mult, H**O))

        if (H**O > 0):
            Na = Na - 1
        else:
            Nb = Nb - 1
        charge = charge + 1
        mult = Na - Nb + 1

    psi4.set_global_option("DF_INTS_IO", "NONE")

    # => Print the results out <= #
    E = {}
    psi4.print_out('\n    ==> Fractional Occupation Nuke Results <==\n\n')
    psi4.print_out('\t%-11s %-24s %-24s %11s\n' %
                   ('N', 'Energy', 'H**O Energy', 'Converged'))
    for k in range(len(Ns)):
        psi4.print_out('\t%11.3E %24.16E %24.16E %11d\n' %
                       (Ns[k], energies[k], potentials[k], convs[k]))
        E[Ns[k]] = energies[k]

    psi4.print_out('\n')
    psi4.print_out('\t%6s %6s %6s %6s %6s %6s\n' %
                   ('N', 'Na', 'Nb', 'Charge', 'Mult', 'H**O'))
    for line in stats:
        psi4.print_out(line)

    psi4.print_out(
        '\n\t"You shoot a nuke down a bug hole, you got a lot of dead bugs"\n')
    psi4.print_out('\t\t\t-Starship Troopers\n')

    # Drop the files out
    fh = open(traverse_filename, 'w')
    fh.write('\t%-11s %-24s %-24s %11s\n' %
             ('N', 'Energy', 'H**O Energy', 'Converged'))
    for k in range(len(Ns)):
        fh.write('\t%11.3E %24.16E %24.16E %11d\n' %
                 (Ns[k], energies[k], potentials[k], convs[k]))
    fh.close()

    fh = open(stats_filename, 'w')
    fh.write('\t%6s %6s %6s %6s %6s %6s\n' %
             ('N', 'Na', 'Nb', 'Charge', 'Mult', 'H**O'))
    for line in stats:
        fh.write(line)
    fh.close()

    return E
Beispiel #9
0
def ip_fitting(mol, omega_l, omega_r, **kwargs):
    kwargs = p4util.kwargs_lower(kwargs)

    # By default, zero the omega to 3 digits
    omega_tol = 1.0E-3;
    if ('omega_tolerance' in kwargs):
        omega_tol = kwargs['omega_tolerance']

    # By default, do up to twenty iterations
    maxiter = 20;
    if ('maxiter' in kwargs):
        maxiter = kwargs['maxiter']

    # By default, do not read previous 180 orbitals file
    read = False;
    read180 = ''
    if ('read' in kwargs):
        read = True;
        read180 = kwargs['read']

    # The molecule is required, and should be the neutral species
    mol.update_geometry()
    activate(mol)
    charge0 = mol.molecular_charge()
    mult0   = mol.multiplicity()

    # How many electrons are there?
    N = 0;
    for A in range(mol.natom()):
        N += mol.Z(A)
    N -= charge0
    N  = int(N)
    Nb = int((N - mult0 + 1)/2)
    Na = int(N - Nb)

    # Work in the ot namespace for this procedure
    psi4.IO.set_default_namespace("ot")

    # Burn in to determine orbital eigenvalues
    if (read):
        psi4.set_global_option("GUESS", "READ")
        copy_file_to_scratch(read180, 'psi', 'ot', 180)
    old_guess = psi4.get_global_option("GUESS")
    psi4.set_global_option("DF_INTS_IO", "SAVE")
    psi4.print_out('\n\t==> IP Fitting SCF: Burn-in <==\n')
    energy('scf')
    psi4.set_global_option("DF_INTS_IO", "LOAD")

    # Determine H**O, to determine mult1
    ref = psi4.wavefunction()
    eps_a = ref.epsilon_a()
    eps_b = ref.epsilon_b()
    if (Na == Nb):
        H**O = -Nb
    elif (Nb == 0):
        H**O = Na
    else:
        E_a = eps_a[int(Na - 1)]
        E_b = eps_b[int(Nb - 1)]
        if (E_a >= E_b):
            H**O = Na
        else:
            H**O = -Nb

    Na1 = Na;
    Nb1 = Nb;
    if (H**O > 0):
        Na1 = Na1-1;
    else:
        Nb1 = Nb1-1;

    charge1 = charge0 + 1;
    mult1 = Na1 - Nb1 + 1

    omegas = [];
    E0s = [];
    E1s = [];
    kIPs = [];
    IPs = [];
    types = [];

    # Right endpoint
    psi4.set_global_option('DFT_OMEGA',omega_r)

    # Neutral
    if (read):
        psi4.set_global_option("GUESS", "READ")
        p4util.copy_file_to_scratch(read180, 'psi', 'ot', 180)

    mol.set_molecular_charge(charge0)
    mol.set_multiplicity(mult0)
    psi4.print_out('\n\t==> IP Fitting SCF: Neutral, Right Endpoint <==\n')
    E0r = energy('scf')
    ref = psi4.wavefunction()
    eps_a = ref.epsilon_a()
    eps_b = ref.epsilon_b()
    E_HOMO = 0.0;
    if (Nb == 0):
        E_HOMO = eps_a[int(Na-1)]
    else:
        E_a = eps_a[int(Na - 1)]
        E_b = eps_b[int(Nb - 1)]
        if (E_a >= E_b):
            E_HOMO = E_a;
        else:
            E_HOMO = E_b;
    E_HOMOr = E_HOMO;
    psi4.IO.change_file_namespace(180,"ot","neutral")

    # Cation
    if (read):
        psi4.set_global_option("GUESS", "READ")
        p4util.copy_file_to_scratch(read180, 'psi', 'ot', 180)

    mol.set_molecular_charge(charge1)
    mol.set_multiplicity(mult1)
    psi4.print_out('\n\t==> IP Fitting SCF: Cation, Right Endpoint <==\n')
    E1r = energy('scf')
    psi4.IO.change_file_namespace(180,"ot","cation")

    IPr = E1r - E0r;
    kIPr = -E_HOMOr;
    delta_r = IPr - kIPr;

    if (IPr > kIPr):
        message = ('\n***IP Fitting Error: Right Omega limit should have kIP > IP')
        raise ValidationError(message)

    omegas.append(omega_r)
    types.append('Right Limit')
    E0s.append(E0r)
    E1s.append(E1r)
    IPs.append(IPr)
    kIPs.append(kIPr)

    # Use previous orbitals from here out
    psi4.set_global_option("GUESS","READ")

    # Left endpoint
    psi4.set_global_option('DFT_OMEGA',omega_l)

    # Neutral
    psi4.IO.change_file_namespace(180,"neutral","ot")
    mol.set_molecular_charge(charge0)
    mol.set_multiplicity(mult0)
    psi4.print_out('\n\t==> IP Fitting SCF: Neutral, Left Endpoint <==\n')
    E0l = energy('scf')
    ref = psi4.wavefunction()
    eps_a = ref.epsilon_a()
    eps_b = ref.epsilon_b()
    E_HOMO = 0.0;
    if (Nb == 0):
        E_HOMO = eps_a[int(Na-1)]
    else:
        E_a = eps_a[int(Na - 1)]
        E_b = eps_b[int(Nb - 1)]
        if (E_a >= E_b):
            E_HOMO = E_a;
        else:
            E_HOMO = E_b;
    E_HOMOl = E_HOMO;
    psi4.IO.change_file_namespace(180,"ot","neutral")

    # Cation
    psi4.IO.change_file_namespace(180,"cation","ot")
    mol.set_molecular_charge(charge1)
    mol.set_multiplicity(mult1)
    psi4.print_out('\n\t==> IP Fitting SCF: Cation, Left Endpoint <==\n')
    E1l = energy('scf')
    psi4.IO.change_file_namespace(180,"ot","cation")

    IPl = E1l - E0l;
    kIPl = -E_HOMOl;
    delta_l = IPl - kIPl;

    if (IPl < kIPl):
        message = ('\n***IP Fitting Error: Left Omega limit should have kIP < IP')
        raise ValidationError(message)

    omegas.append(omega_l)
    types.append('Left Limit')
    E0s.append(E0l)
    E1s.append(E1l)
    IPs.append(IPl)
    kIPs.append(kIPl)

    converged = False
    repeat_l = 0;
    repeat_r = 0;
    step = 0;
    while True:

        step = step + 1;

        # Regula Falsi (modified)
        if (repeat_l > 1):
            delta_l = delta_l / 2.0;
        if (repeat_r > 1):
            delta_r = delta_r / 2.0;
        omega = - (omega_r - omega_l) / (delta_r - delta_l) * delta_l + omega_l;
        psi4.set_global_option('DFT_OMEGA',omega)

        # Neutral
        psi4.IO.change_file_namespace(180,"neutral","ot")
        mol.set_molecular_charge(charge0)
        mol.set_multiplicity(mult0)
        psi4.print_out('\n\t==> IP Fitting SCF: Neutral, Omega = %11.3E <==\n' % omega)
        E0 = energy('scf')
        ref = psi4.wavefunction()
        eps_a = ref.epsilon_a()
        eps_b = ref.epsilon_b()
        E_HOMO = 0.0;
        if (Nb == 0):
            E_HOMO = eps_a[int(Na-1)]
        else:
            E_a = eps_a[int(Na - 1)]
            E_b = eps_b[int(Nb - 1)]
            if (E_a >= E_b):
                E_HOMO = E_a;
            else:
                E_HOMO = E_b;
        psi4.IO.change_file_namespace(180,"ot","neutral")

        # Cation
        psi4.IO.change_file_namespace(180,"cation","ot")
        mol.set_molecular_charge(charge1)
        mol.set_multiplicity(mult1)
        psi4.print_out('\n\t==> IP Fitting SCF: Cation, Omega = %11.3E <==\n' % omega)
        E1 = energy('scf')
        psi4.IO.change_file_namespace(180,"ot","cation")

        IP = E1 - E0;
        kIP = -E_HOMO;
        delta = IP - kIP;

        if (kIP > IP):
            omega_r = omega
            E0r = E0
            E1r = E1
            IPr = IP
            kIPr = kIP
            delta_r = delta
            repeat_r = 0;
            repeat_l = repeat_l + 1;
        else:
            omega_l = omega
            E0l = E0
            E1l = E1
            IPl = IP
            kIPl = kIP
            delta_l = delta
            repeat_l = 0;
            repeat_r = repeat_r + 1;

        omegas.append(omega)
        types.append('Regula-Falsi')
        E0s.append(E0)
        E1s.append(E1)
        IPs.append(IP)
        kIPs.append(kIP)

        # Termination
        if (abs(omega_l - omega_r) < omega_tol or step > maxiter):
            converged = True;
            break

    psi4.IO.set_default_namespace("")

    psi4.print_out('\n\t==> IP Fitting Results <==\n\n')

    psi4.print_out('\t => Occupation Determination <= \n\n')
    psi4.print_out('\t          %6s %6s %6s %6s %6s %6s\n' %('N', 'Na', 'Nb', 'Charge', 'Mult', 'H**O'))
    psi4.print_out('\t Neutral: %6d %6d %6d %6d %6d %6d\n' %(N, Na, Nb, charge0, mult0, H**O))
    psi4.print_out('\t Cation:  %6d %6d %6d %6d %6d\n\n' %(N-1, Na1, Nb1, charge1, mult1))

    psi4.print_out('\t => Regula Falsi Iterations <=\n\n')
    psi4.print_out('\t%3s %11s %14s %14s %14s %s\n' % ('N','Omega','IP','kIP','Delta','Type'))
    for k in range(len(omegas)):
        psi4.print_out('\t%3d %11.3E %14.6E %14.6E %14.6E %s\n' % (k+1,omegas[k],IPs[k],kIPs[k],IPs[k] - kIPs[k], types[k]))
    if (converged):
        psi4.print_out('\n\tIP Fitting Converged\n')
        psi4.print_out('\tFinal omega = %14.6E\n' % ((omega_l + omega_r) / 2))
        psi4.print_out('\n\t"M,I. does the dying. Fleet just does the flying."\n')
        psi4.print_out('\t\t\t-Starship Troopers\n')

    else:
        psi4.print_out('\n\tIP Fitting did not converge!\n')

    psi4.set_global_option("DF_INTS_IO", "NONE")
    psi4.set_global_option("GUESS", old_guess)
Beispiel #10
0
def frac_traverse(mol, **kwargs):
    kwargs = p4util.kwargs_lower(kwargs)

    # The molecule is required, and should be the neutral species
    mol.update_geometry()
    activate(mol)
    charge0 = mol.molecular_charge()
    mult0   = mol.multiplicity()

    chargep = charge0 + 1
    chargem = charge0 - 1

    # By default, the multiplicity of the cation/anion are mult0 + 1
    # These are overridden with the cation_mult and anion_mult kwargs
    multp = mult0 + 1
    multm = mult0 + 1
    if 'cation_mult' in kwargs:
        multp = kwargs['cation_mult']
    if 'anion_mult' in kwargs:
        multm = kwargs['anion_mult']

    # By default, we start the frac procedure on the 25th iteration
    # when not reading a previous guess
    frac_start = 25
    if 'frac_start' in kwargs:
        frac_start = kwargs['frac_start']

    # By default, we occupy by tenths of electrons
    LUMO_occs = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]
    HOMO_occs  = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]
    if 'HOMO_occs' in kwargs:
        HOMO_occs = kwargs['HOMO_occs']
    if 'LUMO_occs' in kwargs:
        LUMO_occs = kwargs['LUMO_occs']

    # By default, H**O and LUMO are both in alpha
    Z = 0;
    for A in range(mol.natom()):
        Z += mol.Z(A)
    Z -= charge0
    if (Z%2):
        H**O = Z/2+1
    else:
        H**O = Z/2
    LUMO = H**O+1
    if 'H**O' in kwargs:
        H**O = kwargs['H**O']
    if 'LUMO' in kwargs:
        LUMO = kwargs['LUMO']

    # By default, DIIS in FRAC (1.0 occupation is always DIIS'd)
    frac_diis = True
    if 'frac_diis' in kwargs:
        frac_diis = kwargs['frac_diis']

    # By default, use the neutral orbitals as a guess for the anion
    neutral_guess = True
    if 'neutral_guess' in kwargs:
        neutral_guess = kwargs['neutral_guess']

    # By default, burn-in with UHF first, if UKS
    hf_guess = False
    if psi4.get_global_option('REFERENCE') == 'UKS':
        hf_guess = True
        if 'hf_guess' in kwargs:
            hf_guess = kwargs['hf_guess']

    # By default, re-guess at each N
    continuous_guess = False
    if 'continuous_guess' in kwargs:
         continuous_guess = kwargs['continuous_guess']

    # By default, drop the files to the molecule's name
    root = mol.name()
    if 'filename' in kwargs:
        root = kwargs['filename']
    traverse_filename = root + '.traverse.dat'
    # => Traverse <= #
    occs = []
    energies = []
    potentials = []
    convs = []

    # => Run the neutral for its orbitals, if requested <= #

    old_df_ints_io = psi4.get_global_option("DF_INTS_IO")
    psi4.set_global_option("DF_INTS_IO", "SAVE")

    old_guess = psi4.get_global_option("GUESS")
    if (neutral_guess):
        if (hf_guess):
            psi4.set_global_option("REFERENCE","UHF")
        energy('scf')
        psi4.set_global_option("GUESS", "READ")
        psi4.set_global_option("DF_INTS_IO", "LOAD")

    # => Run the anion first <= #

    mol.set_molecular_charge(chargem)
    mol.set_multiplicity(multm)

    # => Burn the anion in with hf, if requested <= #
    if (hf_guess):
        psi4.set_global_option("REFERENCE","UHF")
        energy('scf')
        psi4.set_global_option("REFERENCE","UKS")
        psi4.set_global_option("GUESS", "READ")
        psi4.set_global_option("DF_INTS_IO", "SAVE")

    psi4.set_global_option("FRAC_START", frac_start)
    psi4.set_global_option("FRAC_RENORMALIZE", True)
    psi4.set_global_option("FRAC_LOAD", False)

    for occ in LUMO_occs:

        psi4.set_global_option("FRAC_OCC", [LUMO])
        psi4.set_global_option("FRAC_VAL", [occ])

        E = energy('scf')
        C = 1
        if (E == 0.0):
            E = psi4.get_variable('SCF ITERATION ENERGY')
            C = 0

        if (LUMO > 0):
            ref = psi4.wavefunction()
            eps = ref.epsilon_a()
            potentials.append(eps[int(LUMO)-1])
        else:
            ref = psi4.wavefunction()
            eps = ref.epsilon_b()
            potentials.append(eps[-int(LUMO)-1])

        occs.append(occ)
        energies.append(E)
        convs.append(C)

        psi4.set_global_option("FRAC_START", 2)
        psi4.set_global_option("FRAC_LOAD", True)
        psi4.set_global_option("GUESS", "READ")
        psi4.set_global_option("FRAC_DIIS", frac_diis)
        psi4.set_global_option("DF_INTS_IO", "LOAD")


    # => Run the neutral next <= #

    mol.set_molecular_charge(charge0)
    mol.set_multiplicity(mult0)

    # Burn the neutral in with hf, if requested <= #

    if (not continuous_guess):
        psi4.set_global_option("GUESS", old_guess)
        if (hf_guess):
            psi4.set_global_option("FRAC_START", 0)
            psi4.set_global_option("REFERENCE","UHF")
            energy('scf')
            psi4.set_global_option("REFERENCE","UKS")
            psi4.set_global_option("GUESS", "READ")
        psi4.set_global_option("FRAC_LOAD", False)

    psi4.set_global_option("FRAC_START", frac_start)
    psi4.set_global_option("FRAC_RENORMALIZE", True)

    for occ in HOMO_occs:

        psi4.set_global_option("FRAC_OCC", [H**O])
        psi4.set_global_option("FRAC_VAL", [occ])

        E = energy('scf')
        C = 1
        if (E == 0.0):
            E = psi4.get_variable('SCF ITERATION ENERGY')
            C = 0

        if (LUMO > 0):
            ref = psi4.wavefunction()
            eps = ref.epsilon_a()
            potentials.append(eps[int(H**O)-1])
        else:
            ref = psi4.wavefunction()
            eps = ref.epsilon_b()
            potentials.append(eps[-int(H**O)-1])

        occs.append(occ - 1.0)
        energies.append(E)
        convs.append(C)

        psi4.set_global_option("FRAC_START", 2)
        psi4.set_global_option("FRAC_LOAD", True)
        psi4.set_global_option("GUESS", "READ")
        psi4.set_global_option("FRAC_DIIS", frac_diis)
        psi4.set_global_option("DF_INTS_IO", "LOAD")

    psi4.set_global_option("DF_INTS_IO", old_df_ints_io)

    # => Print the results out <= #
    E = {}
    psi4.print_out('\n    ==> Fractional Occupation Traverse Results <==\n\n')
    psi4.print_out('\t%-11s %-24s %-24s %11s\n' %('N', 'Energy', 'H**O Energy', 'Converged'))
    for k in range(len(occs)):
        psi4.print_out('\t%11.3E %24.16E %24.16E %11d\n' % (occs[k], energies[k], potentials[k], convs[k]))
        E[occs[k]] = energies[k]

    psi4.print_out('\n\t"You trying to be a hero Watkins?"\n')
    psi4.print_out('\t"Just trying to kill some bugs sir!"\n')
    psi4.print_out('\t\t\t-Starship Troopers\n')

    # Drop the files out
    fh = open(traverse_filename, 'w')
    fh.write('\t%-11s %-24s %-24s %11s\n' %('N', 'Energy', 'H**O Energy', 'Converged'))
    for k in range(len(occs)):
        fh.write('\t%11.3E %24.16E %24.16E %11d\n' % (occs[k], energies[k], potentials[k], convs[k]))
    fh.close()

    return E
Beispiel #11
0
def frac_nuke(mol, **kwargs):
    kwargs = p4util.kwargs_lower(kwargs)

    # The molecule is required, and should be the neutral species
    mol.update_geometry()
    activate(mol)
    charge0 = mol.molecular_charge()
    mult0   = mol.multiplicity()

    # By default, we start the frac procedure on the 25th iteration
    # when not reading a previous guess
    frac_start = 25
    if 'frac_start' in kwargs:
        frac_start = kwargs['frac_start']

    # By default, we occupy by tenths of electrons
    foccs = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]
    if 'foccs' in kwargs:
        foccs = kwargs['foccs']

    # By default, H**O and LUMO are both in alpha
    N = 0;
    for A in range(mol.natom()):
        N += mol.Z(A)
    N -= charge0
    N  = int(N)
    Nb = int((N - mult0 + 1)/2)
    Na = int(N - Nb)

    charge = charge0
    mult = mult0

    # By default, nuke all the electrons
    Nmin = 0;
    if ('nmax' in kwargs):
        Nmin = N - int(kwargs['nmax'])

    # By default, DIIS in FRAC (1.0 occupation is always DIIS'd)
    frac_diis = True
    if 'frac_diis' in kwargs:
        frac_diis = kwargs['frac_diis']

    # By default, drop the files to the molecule's name
    root = mol.name()
    if 'filename' in kwargs:
        root = kwargs['filename']
    traverse_filename = root + '.traverse.dat'
    stats_filename = root + '.stats.dat'

    # => Traverse <= #
    psi4.set_global_option("DF_INTS_IO", "SAVE")

    Ns = []
    energies = []
    potentials = []
    convs = []
    stats = []

    # Run one SCF to burn things in
    energy('scf')

    # Determine H**O
    ref = psi4.wavefunction()
    eps_a = ref.epsilon_a()
    eps_b = ref.epsilon_b()
    if (Na == Nb):
        H**O = -Nb
    elif (Nb == 0):
        H**O = Na
    else:
        E_a = eps_a[int(Na - 1)]
        E_b = eps_b[int(Nb - 1)]
        if (E_a >= E_b):
            H**O = Na
        else:
            H**O = -Nb

    stats.append('\t%6d %6d %6d %6d %6d %6d\n' %(N, Na, Nb, charge, mult, H**O))

    if (H**O > 0):
        Na = Na - 1
    else:
        Nb = Nb - 1
    charge = charge + 1
    mult = Na - Nb + 1

    psi4.set_global_option("DF_INTS_IO", "LOAD")
    psi4.set_global_option("FRAC_START", frac_start)
    psi4.set_global_option("FRAC_RENORMALIZE", True)

    # Nuke 'em Rico!
    for Nintegral in range(N,Nmin,-1):

        # Nuke the current H**O
        for occ in foccs:

            psi4.set_global_option("FRAC_OCC", [H**O])
            psi4.set_global_option("FRAC_VAL", [occ])

            E = energy('scf')
            C = 1
            if (E == 0.0):
                E = psi4.get_variable('SCF ITERATION ENERGY')
                C = 0

            if (H**O > 0):
                ref = psi4.wavefunction()
                eps = ref.epsilon_a()
                potentials.append(eps[H**O-1])
            else:
                ref = psi4.wavefunction()
                eps = ref.epsilon_b()
                potentials.append(eps[-H**O-1])

            Ns.append(Nintegral + occ - 1.0)
            energies.append(E)
            convs.append(C)

            psi4.set_global_option("FRAC_START", 2)
            psi4.set_global_option("FRAC_LOAD", True)
            psi4.set_global_option("FRAC_DIIS", frac_diis)
            psi4.set_global_option("GUESS", "READ")

        # Set the next charge/mult
        mol.set_molecular_charge(charge)
        mol.set_multiplicity(mult)

        # Determine H**O
        ref = psi4.wavefunction()
        eps_a = ref.epsilon_a()
        eps_b = ref.epsilon_b()
        if (Na == Nb):
            H**O = -Nb
        elif (Nb == 0):
            H**O = Na
        else:
            E_a = eps_a[int(Na - 1)]
            E_b = eps_b[int(Nb - 1)]
            if (E_a >= E_b):
                H**O = Na
            else:
                H**O = -Nb

        stats.append('\t%6d %6d %6d %6d %6d %6d\n' %(Nintegral-1, Na, Nb, charge, mult, H**O))

        if (H**O > 0):
            Na = Na - 1
        else:
            Nb = Nb - 1
        charge = charge + 1
        mult = Na - Nb + 1

    psi4.set_global_option("DF_INTS_IO", "NONE")

    # => Print the results out <= #
    E = {}
    psi4.print_out('\n    ==> Fractional Occupation Nuke Results <==\n\n')
    psi4.print_out('\t%-11s %-24s %-24s %11s\n' %('N', 'Energy', 'H**O Energy', 'Converged'))
    for k in range(len(Ns)):
        psi4.print_out('\t%11.3E %24.16E %24.16E %11d\n' % (Ns[k], energies[k], potentials[k], convs[k]))
        E[Ns[k]] = energies[k]

    psi4.print_out('\n')
    psi4.print_out('\t%6s %6s %6s %6s %6s %6s\n' %('N', 'Na', 'Nb', 'Charge', 'Mult', 'H**O'))
    for line in stats:
        psi4.print_out(line)

    psi4.print_out('\n\t"You shoot a nuke down a bug hole, you got a lot of dead bugs"\n')
    psi4.print_out('\t\t\t-Starship Troopers\n')

    # Drop the files out
    fh = open(traverse_filename, 'w')
    fh.write('\t%-11s %-24s %-24s %11s\n' %('N', 'Energy', 'H**O Energy', 'Converged'))
    for k in range(len(Ns)):
        fh.write('\t%11.3E %24.16E %24.16E %11d\n' % (Ns[k], energies[k], potentials[k], convs[k]))
    fh.close()

    fh = open(stats_filename, 'w')
    fh.write('\t%6s %6s %6s %6s %6s %6s\n' %('N', 'Na', 'Nb', 'Charge', 'Mult', 'H**O'))
    for line in stats:
        fh.write(line)
    fh.close()

    return E
Beispiel #12
0
def run_gaussian_2(name, **kwargs):

    # throw an exception for open-shells
    if (psi4.get_option('SCF', 'REFERENCE') != 'RHF'):
        raise ValidationError("""g2 computations require "reference rhf".""")

    # stash user options:
    optstash = p4util.OptionsState(['FNOCC', 'COMPUTE_TRIPLES'],
                                   ['FNOCC', 'COMPUTE_MP4_TRIPLES'],
                                   ['FREEZE_CORE'], ['SCF', 'SCF_TYPE'])

    # override default scf_type
    psi4.set_local_option('SCF', 'SCF_TYPE', 'OUT_OF_CORE')

    # optimize geometry at scf level
    psi4.clean()
    psi4.set_global_option('BASIS', "6-31G(D)")
    optimize('scf')
    psi4.clean()

    # scf frequencies for zpe
    frequency('scf')

    # thermodynamic properties
    du = psi4.get_variable('INTERNAL ENERGY CORRECTION')
    dh = psi4.get_variable('ENTHALPY CORRECTION')
    dg = psi4.get_variable('GIBBS FREE ENERGY CORRECTION')

    ref = psi4.wavefunction()
    freqs = ref.frequencies()
    nfreq = freqs.dim(0)
    freqsum = 0.0
    for i in range(0, nfreq):
        freqsum += freqs.get(i)
    zpe = freqsum / p4const.psi_hartree2wavenumbers * 0.8929 * 0.5
    psi4.clean()

    # optimize geometry at mp2 (no frozen core) level
    # note: freeze_core isn't an option in MP2
    psi4.set_global_option('FREEZE_CORE', "FALSE")
    optimize('conv-mp2')
    psi4.clean()

    # qcisd(t)
    psi4.set_local_option('FNOCC', 'COMPUTE_MP4_TRIPLES', "TRUE")
    psi4.set_global_option('FREEZE_CORE', "TRUE")
    psi4.set_global_option('BASIS', "6-311G(D_P)")
    run_fnocc('qcisd(t)', **kwargs)

    # HLC: high-level correction based on number of valence electrons
    ref = psi4.wavefunction()
    nirrep = ref.nirrep()
    frzcpi = ref.frzcpi()
    nfzc = 0
    for i in range(0, nirrep):
        nfzc += frzcpi[i]
    nalpha = ref.nalpha() - nfzc
    nbeta = ref.nbeta() - nfzc
    # hlc of gaussian-2
    hlc = -0.00481 * nalpha - 0.00019 * nbeta
    # hlc of gaussian-1
    hlc1 = -0.00614 * nalpha

    eqci_6311gdp = psi4.get_variable("QCISD(T) TOTAL ENERGY")
    emp4_6311gd = psi4.get_variable("MP4 TOTAL ENERGY")
    emp2_6311gd = psi4.get_variable("MP2 TOTAL ENERGY")
    psi4.clean()

    # correction for diffuse functions
    psi4.set_global_option('BASIS', "6-311+G(D_P)")
    energy('mp4')
    emp4_6311pg_dp = psi4.get_variable("MP4 TOTAL ENERGY")
    emp2_6311pg_dp = psi4.get_variable("MP2 TOTAL ENERGY")
    psi4.clean()

    # correction for polarization functions
    psi4.set_global_option('BASIS', "6-311G(2DF_P)")
    energy('mp4')
    emp4_6311g2dfp = psi4.get_variable("MP4 TOTAL ENERGY")
    emp2_6311g2dfp = psi4.get_variable("MP2 TOTAL ENERGY")
    psi4.clean()

    # big basis mp2
    psi4.set_global_option('BASIS', "6-311+G(3DF_2P)")
    run_fnocc('_mp2', **kwargs)
    emp2_big = psi4.get_variable("MP2 TOTAL ENERGY")
    psi4.clean()

    eqci = eqci_6311gdp
    e_delta_g2 = emp2_big + emp2_6311gd - emp2_6311g2dfp - emp2_6311pg_dp
    e_plus = emp4_6311pg_dp - emp4_6311gd
    e_2df = emp4_6311g2dfp - emp4_6311gd

    eg2 = eqci + e_delta_g2 + e_plus + e_2df
    eg2_mp2_0k = eqci + (emp2_big - emp2_6311gd) + hlc + zpe

    psi4.print_out('\n')
    psi4.print_out('  ==>  G1/G2 Energy Components  <==\n')
    psi4.print_out('\n')
    psi4.print_out('        QCISD(T):            %20.12lf\n' % eqci)
    psi4.print_out('        E(Delta):            %20.12lf\n' % e_delta_g2)
    psi4.print_out('        E(2DF):              %20.12lf\n' % e_2df)
    psi4.print_out('        E(+):                %20.12lf\n' % e_plus)
    psi4.print_out('        E(G1 HLC):           %20.12lf\n' % hlc1)
    psi4.print_out('        E(G2 HLC):           %20.12lf\n' % hlc)
    psi4.print_out('        E(ZPE):              %20.12lf\n' % zpe)
    psi4.print_out('\n')
    psi4.print_out('  ==>  0 Kelvin Results  <==\n')
    psi4.print_out('\n')
    eg2_0k = eg2 + zpe + hlc
    psi4.print_out('        G1:                  %20.12lf\n' %
                   (eqci + e_plus + e_2df + hlc1 + zpe))
    psi4.print_out('        G2(MP2):             %20.12lf\n' % eg2_mp2_0k)
    psi4.print_out('        G2:                  %20.12lf\n' % eg2_0k)

    psi4.set_variable("G1 TOTAL ENERGY", eqci + e_plus + e_2df + hlc1 + zpe)
    psi4.set_variable("G2 TOTAL ENERGY", eg2_0k)
    psi4.set_variable("G2(MP2) TOTAL ENERGY", eg2_mp2_0k)

    psi4.print_out('\n')
    T = psi4.get_global_option('T')
    psi4.print_out('  ==>  %3.0lf Kelvin Results  <==\n' % T)
    psi4.print_out('\n')

    internal_energy = eg2_mp2_0k + du - zpe / 0.8929
    enthalpy = eg2_mp2_0k + dh - zpe / 0.8929
    gibbs = eg2_mp2_0k + dg - zpe / 0.8929

    psi4.print_out('        G2(MP2) energy:      %20.12lf\n' % internal_energy)
    psi4.print_out('        G2(MP2) enthalpy:    %20.12lf\n' % enthalpy)
    psi4.print_out('        G2(MP2) free energy: %20.12lf\n' % gibbs)
    psi4.print_out('\n')

    psi4.set_variable("G2(MP2) INTERNAL ENERGY", internal_energy)
    psi4.set_variable("G2(MP2) ENTHALPY", enthalpy)
    psi4.set_variable("G2(MP2) FREE ENERGY", gibbs)

    internal_energy = eg2_0k + du - zpe / 0.8929
    enthalpy = eg2_0k + dh - zpe / 0.8929
    gibbs = eg2_0k + dg - zpe / 0.8929

    psi4.print_out('        G2 energy:           %20.12lf\n' % internal_energy)
    psi4.print_out('        G2 enthalpy:         %20.12lf\n' % enthalpy)
    psi4.print_out('        G2 free energy:      %20.12lf\n' % gibbs)

    psi4.set_variable("CURRENT ENERGY", eg2_0k)

    psi4.set_variable("G2 INTERNAL ENERGY", internal_energy)
    psi4.set_variable("G2 ENTHALPY", enthalpy)
    psi4.set_variable("G2 FREE ENERGY", gibbs)

    psi4.clean()

    optstash.restore()

    # return 0K g2 results
    return eg2_0k