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')
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')
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 ref_wfn = kwargs.get('ref_wfn', None) if ref_wfn is None: ref_wfn = driver.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 = ref_wfn.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.get_option('SCF', 'SCF_TYPE') if ( scf_type == 'PK' or scf_type == 'DIRECT' ): proc_util.check_iwl_file_from_scf_type(psi4.get_option('SCF', 'SCF_TYPE'), ref_wfn) returnvalue = psi4.plugin('v2rdm_casscf.so', ref_wfn) #psi4.set_variable('CURRENT ENERGY', returnvalue) #return psi4.get_variable('CURRENT ENERGY') return returnvalue
def ip_fitting(molecule, omega_l, omega_r, **kwargs): kwargs = p4util.kwargs_lower(kwargs) # By default, zero the omega to 3 digits omega_tol = kwargs.get('omega_tolerance', 1.0E-3) # By default, do up to twenty iterations maxiter = kwargs.get('maxiter', 20) # 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 molecule.update_geometry() charge0 = molecule.molecular_charge() mult0 = molecule.multiplicity() # How many electrons are there? N = 0 for A in range(molecule.natom()): N += molecule.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""") E, wfn = energy('scf', return_wfn=True, molecule=molecule, **kwargs) psi4.set_global_option("DF_INTS_IO", "LOAD") # Determine H**O, to determine mult1 eps_a = wfn.epsilon_a() eps_b = wfn.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) molecule.set_molecular_charge(charge0) molecule.set_multiplicity(mult0) psi4.print_out("""\n\t==> IP Fitting SCF: Neutral, Right Endpoint <==\n""") E0r, wfn = energy('scf', return_wfn=True, molecule=molecule, **kwargs) eps_a = wfn.epsilon_a() eps_b = wfn.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) molecule.set_molecular_charge(charge1) molecule.set_multiplicity(mult1) psi4.print_out("""\n\t==> IP Fitting SCF: Cation, Right Endpoint <==\n""") E1r = energy('scf', molecule=molecule, **kwargs) 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") molecule.set_molecular_charge(charge0) molecule.set_multiplicity(mult0) psi4.print_out("""\n\t==> IP Fitting SCF: Neutral, Left Endpoint <==\n""") E0l, wfn = energy('scf', return_wfn=True, molecule=molecule, **kwargs) eps_a = wfn.epsilon_a() eps_b = wfn.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") molecule.set_molecular_charge(charge1) molecule.set_multiplicity(mult1) psi4.print_out("""\n\t==> IP Fitting SCF: Cation, Left Endpoint <==\n""") E1l = energy('scf', molecule=molecule, **kwargs) 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") molecule.set_molecular_charge(charge0) molecule.set_multiplicity(mult0) psi4.print_out( """\n\t==> IP Fitting SCF: Neutral, Omega = %11.3E <==\n""" % omega) E0, wfn = energy('scf', return_wfn=True, molecule=molecule, **kwargs) eps_a = wfn.epsilon_a() eps_b = wfn.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") molecule.set_molecular_charge(charge1) molecule.set_multiplicity(mult1) psi4.print_out( """\n\t==> IP Fitting SCF: Cation, Omega = %11.3E <==\n""" % omega) E1 = energy('scf', molecule=molecule, **kwargs) 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 # Properly, should clone molecule but since not returned and easy to unblemish, molecule.set_molecular_charge(charge0) molecule.set_multiplicity(mult0) 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)
def ip_fitting(molecule, omega_l, omega_r, **kwargs): kwargs = p4util.kwargs_lower(kwargs) # By default, zero the omega to 3 digits omega_tol = kwargs.get('omega_tolerance', 1.0E-3) # By default, do up to twenty iterations maxiter = kwargs.get('maxiter', 20) # 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 molecule.update_geometry() charge0 = molecule.molecular_charge() mult0 = molecule.multiplicity() # How many electrons are there? N = 0 for A in range(molecule.natom()): N += molecule.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""") E, wfn = energy('scf', return_wfn=True, molecule=molecule, **kwargs) psi4.set_global_option("DF_INTS_IO", "LOAD") # Determine H**O, to determine mult1 eps_a = wfn.epsilon_a() eps_b = wfn.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) molecule.set_molecular_charge(charge0) molecule.set_multiplicity(mult0) psi4.print_out("""\n\t==> IP Fitting SCF: Neutral, Right Endpoint <==\n""") E0r, wfn = energy('scf', return_wfn=True, molecule=molecule, **kwargs) eps_a = wfn.epsilon_a() eps_b = wfn.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) molecule.set_molecular_charge(charge1) molecule.set_multiplicity(mult1) psi4.print_out("""\n\t==> IP Fitting SCF: Cation, Right Endpoint <==\n""") E1r = energy('scf', molecule=molecule, **kwargs) 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") molecule.set_molecular_charge(charge0) molecule.set_multiplicity(mult0) psi4.print_out("""\n\t==> IP Fitting SCF: Neutral, Left Endpoint <==\n""") E0l, wfn = energy('scf', return_wfn=True, molecule=molecule, **kwargs) eps_a = wfn.epsilon_a() eps_b = wfn.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") molecule.set_molecular_charge(charge1) molecule.set_multiplicity(mult1) psi4.print_out("""\n\t==> IP Fitting SCF: Cation, Left Endpoint <==\n""") E1l = energy('scf', molecule=molecule, **kwargs) 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") molecule.set_molecular_charge(charge0) molecule.set_multiplicity(mult0) psi4.print_out("""\n\t==> IP Fitting SCF: Neutral, Omega = %11.3E <==\n""" % omega) E0, wfn = energy('scf', return_wfn=True, molecule=molecule, **kwargs) eps_a = wfn.epsilon_a() eps_b = wfn.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") molecule.set_molecular_charge(charge1) molecule.set_multiplicity(mult1) psi4.print_out("""\n\t==> IP Fitting SCF: Cation, Omega = %11.3E <==\n""" % omega) E1 = energy('scf', molecule=molecule, **kwargs) 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 # Properly, should clone molecule but since not returned and easy to unblemish, molecule.set_molecular_charge(charge0) molecule.set_multiplicity(mult0) 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)
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)