def run_mydft(name, **kwargs): r"""Function encoding sequence of PSI module and plugin calls so that mydft can be called via :py:func:`~driver.energy`. For post-scf plugins. >>> energy('mydft') """ #lowername = name.lower() kwargs = p4util.kwargs_lower(kwargs) # Your plugin's psi4 run sequence goes here scf_wfn = kwargs.get('ref_wfn', None) if scf_wfn is None: func = psi4.core.get_option('MYDFT', 'FUNCTIONAL') scf_molecule = kwargs.get('molecule', psi4.core.get_active_molecule()) base_wfn = psi4.core.Wavefunction.build( scf_molecule, psi4.core.get_global_option('BASIS')) scf_wfn = proc.scf_wavefunction_factory( func, base_wfn, psi4.core.get_option('SCF', 'REFERENCE')) # Ensure IWL files have been written when not using DF/CD proc_util.check_iwl_file_from_scf_type( psi4.core.get_option('SCF', 'SCF_TYPE'), scf_wfn) # Call the Psi4 plugin # Please note that setting the reference wavefunction in this way is ONLY for plugins mydft_wfn = psi4.core.plugin('mydft.so', scf_wfn) return mydft_wfn
def run_cis(name, **kwargs): r"""Function encoding sequence of PSI module and plugin calls so that cis can be called via :py:func:`~driver.energy`. For post-scf plugins. >>> energy('cis') """ lowername = name.lower() kwargs = p4util.kwargs_lower(kwargs) # Your plugin's psi4 run sequence goes here psi4.core.set_local_option('MYPLUGIN', 'PRINT', 1) # Compute a SCF reference, a wavefunction is return which holds the molecule used, orbitals # Fock matrices, and more print('Attention! This SCF may be density-fitted.') ref_wfn = kwargs.get('ref_wfn', None) if ref_wfn is None: ref_wfn = psi4.driver.scf_helper(name, **kwargs) # Ensure IWL files have been written when not using DF/CD proc_util.check_iwl_file_from_scf_type( psi4.core.get_option('SCF', 'SCF_TYPE'), ref_wfn) # Call the Psi4 plugin # Please note that setting the reference wavefunction in this way is ONLY for plugins cis_wfn = psi4.core.plugin('cis.so', ref_wfn) return cis_wfn
def run_cct3(name, **kwargs): r"""Function encoding sequence of PSI module and plugin calls so that cct3 can be called via :py:func:`~driver.energy`. For post-scf plugins. >>> energy('cct3') """ lowername = name.lower() kwargs = p4util.kwargs_lower(kwargs) optstash = p4util.OptionsState(['CCT3', 'CALC_TYPE']) # Your plugin's psi4 run sequence goes here if lowername == "cct3": pass elif lowername == "ccsd": psi4.core.set_local_option("CCT3", "CALC_TYPE", "CCSD") elif lowername == "cr-cc(2,3)": psi4.core.set_local_option("CCT3", "CALC_TYPE", "CR-CC") elif lowername == "ccsd_lct": # CCSDt psi4.core.set_local_option("CCT3", "CALC_TYPE", "CCSD3A") elif lowername == "cc(t;3)": psi4.core.set_local_option("CCT3", "CALC_TYPE", "CCT3") # Compute a SCF reference, a wavefunction is return which holds the molecule used, orbitals # Fock matrices, and more ref_wfn = kwargs.get('ref_wfn', None) if ref_wfn is None: ref_wfn = psi4.driver.scf_helper(name, **kwargs) # Ensure IWL files have been written when not using DF/CD proc_util.check_iwl_file_from_scf_type( psi4.core.get_option('SCF', 'SCF_TYPE'), ref_wfn) # Call the Psi4 plugin # Please note that setting the reference wavefunction in this way is ONLY for plugins cct3_wfn = psi4.core.plugin('cct3.so', ref_wfn) try: cct3_wfn.set_module("cct3") except AttributeError: pass # pre-July 2020 psi4 # Shove variables into global space for k, v in cct3_wfn.variables().items(): psi4.core.set_variable(k, v) optstash.restore() return cct3_wfn
def run_rhf_dlmg2b(name, **kwargs): r"""Function encoding sequence of PSI module and plugin calls so that rhf_dlmg2b can be called via :py:func:`~driver.energy`. For post-scf plugins. >>> energy('rhf_dlmg2b') """ lowername = name.lower() kwargs = p4util.kwargs_lower(kwargs) # Your plugin's psi4 run sequence goes here psi4.core.set_local_option('MYPLUGIN', 'PRINT', 1) # Compute a SCF reference, a wavefunction is return which holds the molecule used, orbitals # Fock matrices, and more print('Attention! This SCF may be density-fitted.') ref_wfn = kwargs.get('ref_wfn', None) if ref_wfn is None: ref_wfn = psi4.driver.scf_helper(name, **kwargs) # Ensure IWL files have been written when not using DF/CD proc_util.check_iwl_file_from_scf_type( psi4.core.get_option('SCF', 'SCF_TYPE'), ref_wfn) # Call the Psi4 plugin psi4.core.set_global_option('GUESS', 'READ') optstash = p4util.OptionsState(['E_CONVERGENCE']) psi4.core.set_global_option('E_CONVERGENCE', 1492.) # Please note that setting the reference wavefunction in this way is ONLY for plugins vac_wfn = psi4.core.plugin('rhf_dlmg2b.so', ref_wfn) # Vacuum wfn has been returned. Start solvent calc psi4.core.set_local_option('RHF_DLMG2B', 'eps', psi4.core.get_option('RHF_DLMG2B', 'eps_sol')) # If eps_sol set to zero, return vacuum wfn test_eps = psi4.core.get_option('RHF_DLMG2B', 'eps_sol') optstash.restore() if (test_eps == 0.0): print("Vac_wfn being returned now") return vac_wfn # Do solvent scf sol_wfn = psi4.core.plugin('rhf_dlmg2b.so', vac_wfn) kwargs['ref_wfn'] = sol_wfn return sol_wfn
def run_fcidump(name, **kwargs): r"""Function encoding sequence of PSI module and plugin calls so that fcidump can be called via :py:func:`~driver.energy`. >>> energy('fcidump') """ lowername = name.lower() kwargs = p4util.kwargs_lower(kwargs) # 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) proc_util.check_iwl_file_from_scf_type(psi4.core.get_option('SCF', 'SCF_TYPE'), ref_wfn) test_wfn = psi4.core.plugin('fcidump.so', ref_wfn) return test_wfn
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
def run_erpa(name, **kwargs): r"""Function encoding sequence of PSI module and plugin calls so that erpa can be called via :py:func:`~driver.energy`. For post-scf plugins. >>> energy('erpa') """ 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') erpa_corr_global = psi4.core.get_option('ERPA', 'ERPA_CORRELATION') erpa_corr_local = psi4.core.get_global_option('ERPA_CORRELATION') if not erpa_corr_global and not erpa_corr_local: nat_orbs_global = psi4.core.get_option('V2RDM_CASSCF', 'NAT_ORBS') nat_orbs_local = psi4.core.get_global_option('NAT_ORBS') if not nat_orbs_global and not nat_orbs_local: raise psi4.ValidationError( """ERPA requires that the V2RDM_CASSCF option "nat_orbs" be set to true.""" ) # 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) # 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('erpa.so', ref_wfn) # optstash.restore() return returnvalue
def run_ugacc(name, **kwargs): r"""Function encoding sequence of PSI module and plugin calls so that ugacc can be called via :py:func:`~driver.energy`. For post-scf plugins. >>> energy('ugacc') """ lowername = name.lower() kwargs = p4util.kwargs_lower(kwargs) # Your plugin's psi4 run sequence goes here if ('wfn' in kwargs): if (kwargs['wfn'] == 'ccsd'): psi4.core.set_global_option('WFN', 'CCSD') elif (kwargs['wfn'] == 'ccsd(t)'): psi4.core.set_global_option('WFN', 'CCSD_T') scf_wfn = kwargs.get('ref_wfn', None) if scf_wfn is None: scf_wfn = psi4.driver.scf_helper(name, **kwargs) proc_util.check_iwl_file_from_scf_type(psi4.core.get_option('SCF', 'SCF_TYPE'), scf_wfn) return psi4.core.plugin('ugacc.so', scf_wfn)
def run_libresponse_psi4(name, **kwargs): r"""Function encoding sequence of PSI module and plugin calls so that libresponse_psi4 can be called via :py:func:`~driver.energy`. For post-scf plugins. >>> energy('libresponse_psi4') """ kwargs = p4util.kwargs_lower(kwargs) # Your plugin's psi4 run sequence goes here psi4.core.set_local_option("MYPLUGIN", "PRINT", 1) # The response density is asymmetric; need to build generalized # J/K. proc_util.check_non_symmetric_jk_density("libresponse") # Disable symmetry, even for passed-in wavefunctions. molecule = kwargs.get("molecule", None) if molecule is None: molecule = psi4.core.get_active_molecule() molecule = disable_symmetry(molecule) kwargs["molecule"] = molecule # Compute a SCF reference, a wavefunction is return which holds the # molecule used, orbitals Fock matrices, and more ref_wfn = kwargs.get("ref_wfn", None) if ref_wfn is None: ref_wfn = psi4.driver.scf_helper(name, **kwargs) # Ensure IWL files have been written when not using DF/CD proc_util.check_iwl_file_from_scf_type( psi4.core.get_option("SCF", "SCF_TYPE"), ref_wfn) # Call the Psi4 plugin # Please note that setting the reference wavefunction in this way is ONLY for plugins libresponse_psi4_wfn = psi4.core.plugin("libresponse_psi4.so", ref_wfn) return libresponse_psi4_wfn
def run_ccreorg(name, **kwargs): """Function encoding sequence of PSI module and plugin calls so that ccreorg can be called via :py:func:`~driver.energy`. For post-scf plugins. >>> energy('ccreorg') """ lowername = name.lower() kwargs = p4util.kwargs_lower(kwargs) # Your plugin's psi4 run sequence goes here if ('wfn' in kwargs): if (kwargs['wfn'] == 'ccsd'): psi4.core.set_global_option('WFN', 'CCSD') elif (kwargs['wfn'] == 'ccsd(t)'): psi4.core.set_global_option('WFN', 'CCSD_T') scf_wfn = kwargs.get('ref_wfn', None) if scf_wfn is None: scf_wfn = psi4.driver.scf_helper(name, **kwargs) proc_util.check_iwl_file_from_scf_type( psi4.core.get_option('SCF', 'SCF_TYPE'), scf_wfn) return psi4.core.plugin('ccreorg.so', scf_wfn)
def fcidump(wfn, fname='INTDUMP', oe_ints=None): """Save integrals to file in FCIDUMP format as defined in Comp. Phys. Commun. 54 75 (1989) Additional one-electron integrals, including orbital energies, can also be saved. This latter format can be used with the HANDE QMC code but is not standard. :returns: None :raises: ValidationError when SCF wavefunction is not RHF :type wfn: :py:class:`~psi4.core.Wavefunction` :param wfn: set of molecule, basis, orbitals from which to generate cube files :param fname: name of the integrals file, defaults to INTDUMP :param oe_ints: list of additional one-electron integrals to save to file. So far only EIGENVALUES is a valid option. :examples: >>> # [1] Save one- and two-electron integrals to standard FCIDUMP format >>> E, wfn = energy('scf', return_wfn=True) >>> fcidump(wfn) >>> # [2] Save orbital energies, one- and two-electron integrals. >>> E, wfn = energy('scf', return_wfn=True) >>> fcidump(wfn, oe_ints=['EIGENVALUES']) """ # Get some options reference = core.get_option('SCF', 'REFERENCE') ints_tolerance = core.get_global_option('INTS_TOLERANCE') # Some sanity checks if reference not in ['RHF', 'UHF']: raise ValidationError( 'FCIDUMP not implemented for {} references\n'.format(reference)) if oe_ints is None: oe_ints = [] molecule = wfn.molecule() docc = wfn.doccpi() frzcpi = wfn.frzcpi() frzvpi = wfn.frzvpi() active_docc = docc - frzcpi active_socc = wfn.soccpi() active_mopi = wfn.nmopi() - frzcpi - frzvpi nbf = active_mopi.sum() if wfn.same_a_b_orbs() else 2 * active_mopi.sum() nirrep = wfn.nirrep() nelectron = 2 * active_docc.sum() + active_socc.sum() irrep_map = _irrep_map(wfn) wfn_irrep = 0 for h, n_socc in enumerate(active_socc): if n_socc % 2 == 1: wfn_irrep ^= h core.print_out('Writing integrals in FCIDUMP format to ' + fname + '\n') # Generate FCIDUMP header header = '&FCI\n' header += 'NORB={:d},\n'.format(nbf) header += 'NELEC={:d},\n'.format(nelectron) header += 'MS2={:d},\n'.format(wfn.nalpha() - wfn.nbeta()) header += 'UHF=.{}.,\n'.format(not wfn.same_a_b_orbs()).upper() orbsym = '' for h in range(active_mopi.n()): for n in range(frzcpi[h], frzcpi[h] + active_mopi[h]): orbsym += '{:d},'.format(irrep_map[h]) if not wfn.same_a_b_orbs(): orbsym += '{:d},'.format(irrep_map[h]) header += 'ORBSYM={}\n'.format(orbsym) header += 'ISYM={:d},\n'.format(irrep_map[wfn_irrep]) header += '&END\n' with open(fname, 'w') as intdump: intdump.write(header) # Get an IntegralTransform object check_iwl_file_from_scf_type(core.get_global_option('SCF_TYPE'), wfn) spaces = [core.MOSpace.all()] trans_type = core.IntegralTransform.TransformationType.Restricted if not wfn.same_a_b_orbs(): trans_type = core.IntegralTransform.TransformationType.Unrestricted ints = core.IntegralTransform(wfn, spaces, trans_type) ints.transform_tei(core.MOSpace.all(), core.MOSpace.all(), core.MOSpace.all(), core.MOSpace.all()) core.print_out('Integral transformation complete!\n') DPD_info = { 'instance_id': ints.get_dpd_id(), 'alpha_MO': ints.DPD_ID('[A>=A]+'), 'beta_MO': 0 } if not wfn.same_a_b_orbs(): DPD_info['beta_MO'] = ints.DPD_ID("[a>=a]+") # Write TEI to fname in FCIDUMP format core.fcidump_tei_helper(nirrep, wfn.same_a_b_orbs(), DPD_info, ints_tolerance, fname) # Read-in OEI and write them to fname in FCIDUMP format # Indexing functions to translate from zero-based (C and Python) to # one-based (Fortran) mo_idx = lambda x: x + 1 alpha_mo_idx = lambda x: 2 * x + 1 beta_mo_idx = lambda x: 2 * (x + 1) with open(fname, 'a') as intdump: core.print_out('Writing frozen core operator in FCIDUMP format to ' + fname + '\n') if reference == 'RHF': PSIF_MO_FZC = 'MO-basis Frozen-Core Operator' moH = core.Matrix(PSIF_MO_FZC, wfn.nmopi(), wfn.nmopi()) moH.load(core.IO.shared_object(), psif.PSIF_OEI) mo_slice = core.Slice(frzcpi, active_mopi) MO_FZC = moH.get_block(mo_slice, mo_slice) offset = 0 for h, block in enumerate(MO_FZC.nph): il = np.tril_indices(block.shape[0]) for index, x in np.ndenumerate(block[il]): row = mo_idx(il[0][index] + offset) col = mo_idx(il[1][index] + offset) if (abs(x) > ints_tolerance): intdump.write('{:29.20E}{:4d}{:4d}{:4d}{:4d}\n'.format( x, row, col, 0, 0)) offset += block.shape[0] # Additional one-electron integrals as requested in oe_ints # Orbital energies core.print_out('Writing orbital energies in FCIDUMP format to ' + fname + '\n') if 'EIGENVALUES' in oe_ints: eigs_dump = write_eigenvalues( wfn.epsilon_a().get_block(mo_slice).to_array(), mo_idx) intdump.write(eigs_dump) else: PSIF_MO_A_FZC = 'MO-basis Alpha Frozen-Core Oper' moH_A = core.Matrix(PSIF_MO_A_FZC, wfn.nmopi(), wfn.nmopi()) moH_A.load(core.IO.shared_object(), psif.PSIF_OEI) mo_slice = core.Slice(frzcpi, active_mopi) MO_FZC_A = moH_A.get_block(mo_slice, mo_slice) offset = 0 for h, block in enumerate(MO_FZC_A.nph): il = np.tril_indices(block.shape[0]) for index, x in np.ndenumerate(block[il]): row = alpha_mo_idx(il[0][index] + offset) col = alpha_mo_idx(il[1][index] + offset) if (abs(x) > ints_tolerance): intdump.write('{:29.20E}{:4d}{:4d}{:4d}{:4d}\n'.format( x, row, col, 0, 0)) offset += block.shape[0] PSIF_MO_B_FZC = 'MO-basis Beta Frozen-Core Oper' moH_B = core.Matrix(PSIF_MO_B_FZC, wfn.nmopi(), wfn.nmopi()) moH_B.load(core.IO.shared_object(), psif.PSIF_OEI) mo_slice = core.Slice(frzcpi, active_mopi) MO_FZC_B = moH_B.get_block(mo_slice, mo_slice) offset = 0 for h, block in enumerate(MO_FZC_B.nph): il = np.tril_indices(block.shape[0]) for index, x in np.ndenumerate(block[il]): row = beta_mo_idx(il[0][index] + offset) col = beta_mo_idx(il[1][index] + offset) if (abs(x) > ints_tolerance): intdump.write('{:29.20E}{:4d}{:4d}{:4d}{:4d}\n'.format( x, row, col, 0, 0)) offset += block.shape[0] # Additional one-electron integrals as requested in oe_ints # Orbital energies core.print_out('Writing orbital energies in FCIDUMP format to ' + fname + '\n') if 'EIGENVALUES' in oe_ints: alpha_eigs_dump = write_eigenvalues( wfn.epsilon_a().get_block(mo_slice).to_array(), alpha_mo_idx) beta_eigs_dump = write_eigenvalues( wfn.epsilon_b().get_block(mo_slice).to_array(), beta_mo_idx) intdump.write(alpha_eigs_dump + beta_eigs_dump) # Dipole integrals #core.print_out('Writing dipole moment OEI in FCIDUMP format to ' + fname + '\n') # Traceless quadrupole integrals #core.print_out('Writing traceless quadrupole moment OEI in FCIDUMP format to ' + fname + '\n') # Frozen core + nuclear repulsion energy core.print_out( 'Writing frozen core + nuclear repulsion energy in FCIDUMP format to ' + fname + '\n') e_fzc = ints.get_frozen_core_energy() e_nuc = molecule.nuclear_repulsion_energy( wfn.get_dipole_field_strength()) intdump.write('{:29.20E}{:4d}{:4d}{:4d}{:4d}\n'.format( e_fzc + e_nuc, 0, 0, 0, 0)) core.print_out( 'Done generating {} with integrals in FCIDUMP format.\n'.format(fname))
def fcidump(wfn, fname='INTDUMP', oe_ints=None): """Save integrals to file in FCIDUMP format as defined in Comp. Phys. Commun. 54 75 (1989) Additional one-electron integrals, including orbital energies, can also be saved. This latter format can be used with the HANDE QMC code but is not standard. :returns: None :raises: ValidationError when SCF wavefunction is not RHF :type wfn: :py:class:`~psi4.core.Wavefunction` :param wfn: set of molecule, basis, orbitals from which to generate cube files :param fname: name of the integrals file, defaults to INTDUMP :param oe_ints: list of additional one-electron integrals to save to file. So far only EIGENVALUES is a valid option. :examples: >>> # [1] Save one- and two-electron integrals to standard FCIDUMP format >>> E, wfn = energy('scf', return_wfn=True) >>> fcidump(wfn) >>> # [2] Save orbital energies, one- and two-electron integrals. >>> E, wfn = energy('scf', return_wfn=True) >>> fcidump(wfn, oe_ints=['EIGENVALUES']) """ # Get some options reference = core.get_option('SCF', 'REFERENCE') ints_tolerance = core.get_global_option('INTS_TOLERANCE') # Some sanity checks if reference not in ['RHF', 'UHF']: raise ValidationError('FCIDUMP not implemented for {} references\n'.format(reference)) if oe_ints is None: oe_ints = [] molecule = wfn.molecule() docc = wfn.doccpi() frzcpi = wfn.frzcpi() frzvpi = wfn.frzvpi() active_docc = docc - frzcpi active_socc = wfn.soccpi() active_mopi = wfn.nmopi() - frzcpi - frzvpi nbf = active_mopi.sum() if wfn.same_a_b_orbs() else 2 * active_mopi.sum() nirrep = wfn.nirrep() nelectron = 2 * active_docc.sum() + active_socc.sum() core.print_out('Writing integrals in FCIDUMP format to ' + fname + '\n') # Generate FCIDUMP header header = '&FCI\n' header += 'NORB={:d},\n'.format(nbf) header += 'NELEC={:d},\n'.format(nelectron) header += 'MS2={:d},\n'.format(wfn.nalpha() - wfn.nbeta()) header += 'UHF=.{}.,\n'.format(not wfn.same_a_b_orbs()).upper() orbsym = '' for h in range(active_mopi.n()): for n in range(frzcpi[h], frzcpi[h] + active_mopi[h]): orbsym += '{:d},'.format(h + 1) if not wfn.same_a_b_orbs(): orbsym += '{:d},'.format(h + 1) header += 'ORBSYM={}\n'.format(orbsym) header += '&END\n' with open(fname, 'w') as intdump: intdump.write(header) # Get an IntegralTransform object check_iwl_file_from_scf_type(core.get_global_option('SCF_TYPE'), wfn) spaces = [core.MOSpace.all()] trans_type = core.IntegralTransform.TransformationType.Restricted if not wfn.same_a_b_orbs(): trans_type = core.IntegralTransform.TransformationType.Unrestricted ints = core.IntegralTransform(wfn, spaces, trans_type) ints.transform_tei(core.MOSpace.all(), core.MOSpace.all(), core.MOSpace.all(), core.MOSpace.all()) core.print_out('Integral transformation complete!\n') DPD_info = {'instance_id': ints.get_dpd_id(), 'alpha_MO': ints.DPD_ID('[A>=A]+'), 'beta_MO': 0} if not wfn.same_a_b_orbs(): DPD_info['beta_MO'] = ints.DPD_ID("[a>=a]+") # Write TEI to fname in FCIDUMP format core.fcidump_tei_helper(nirrep, wfn.same_a_b_orbs(), DPD_info, ints_tolerance, fname) # Read-in OEI and write them to fname in FCIDUMP format # Indexing functions to translate from zero-based (C and Python) to # one-based (Fortran) mo_idx = lambda x: x + 1 alpha_mo_idx = lambda x: 2 * x + 1 beta_mo_idx = lambda x: 2 * (x + 1) with open(fname, 'a') as intdump: core.print_out('Writing frozen core operator in FCIDUMP format to ' + fname + '\n') if reference == 'RHF': PSIF_MO_FZC = 'MO-basis Frozen-Core Operator' moH = core.Matrix(PSIF_MO_FZC, wfn.nmopi(), wfn.nmopi()) moH.load(core.IO.shared_object(), psif.PSIF_OEI) mo_slice = core.Slice(frzcpi, active_mopi) MO_FZC = moH.get_block(mo_slice, mo_slice) offset = 0 for h, block in enumerate(MO_FZC.nph): il = np.tril_indices(block.shape[0]) for index, x in np.ndenumerate(block[il]): row = mo_idx(il[0][index] + offset) col = mo_idx(il[1][index] + offset) if (abs(x) > ints_tolerance): intdump.write('{:29.20E} {:4d} {:4d} {:4d} {:4d}\n'.format(x, row, col, 0, 0)) offset += block.shape[0] # Additional one-electron integrals as requested in oe_ints # Orbital energies core.print_out('Writing orbital energies in FCIDUMP format to ' + fname + '\n') if 'EIGENVALUES' in oe_ints: eigs_dump = write_eigenvalues(wfn.epsilon_a().get_block(mo_slice).to_array(), mo_idx) intdump.write(eigs_dump) else: PSIF_MO_A_FZC = 'MO-basis Alpha Frozen-Core Oper' moH_A = core.Matrix(PSIF_MO_A_FZC, wfn.nmopi(), wfn.nmopi()) moH_A.load(core.IO.shared_object(), psif.PSIF_OEI) mo_slice = core.Slice(frzcpi, active_mopi) MO_FZC_A = moH_A.get_block(mo_slice, mo_slice) offset = 0 for h, block in enumerate(MO_FZC_A.nph): il = np.tril_indices(block.shape[0]) for index, x in np.ndenumerate(block[il]): row = alpha_mo_idx(il[0][index] + offset) col = alpha_mo_idx(il[1][index] + offset) if (abs(x) > ints_tolerance): intdump.write('{:29.20E} {:4d} {:4d} {:4d} {:4d}\n'.format(x, row, col, 0, 0)) offset += block.shape[0] PSIF_MO_B_FZC = 'MO-basis Beta Frozen-Core Oper' moH_B = core.Matrix(PSIF_MO_B_FZC, wfn.nmopi(), wfn.nmopi()) moH_B.load(core.IO.shared_object(), psif.PSIF_OEI) mo_slice = core.Slice(frzcpi, active_mopi) MO_FZC_B = moH_B.get_block(mo_slice, mo_slice) offset = 0 for h, block in enumerate(MO_FZC_B.nph): il = np.tril_indices(block.shape[0]) for index, x in np.ndenumerate(block[il]): row = beta_mo_idx(il[0][index] + offset) col = beta_mo_idx(il[1][index] + offset) if (abs(x) > ints_tolerance): intdump.write('{:29.20E} {:4d} {:4d} {:4d} {:4d}\n'.format(x, row, col, 0, 0)) offset += block.shape[0] # Additional one-electron integrals as requested in oe_ints # Orbital energies core.print_out('Writing orbital energies in FCIDUMP format to ' + fname + '\n') if 'EIGENVALUES' in oe_ints: alpha_eigs_dump = write_eigenvalues(wfn.epsilon_a().get_block(mo_slice).to_array(), alpha_mo_idx) beta_eigs_dump = write_eigenvalues(wfn.epsilon_b().get_block(mo_slice).to_array(), beta_mo_idx) intdump.write(alpha_eigs_dump + beta_eigs_dump) # Dipole integrals #core.print_out('Writing dipole moment OEI in FCIDUMP format to ' + fname + '\n') # Traceless quadrupole integrals #core.print_out('Writing traceless quadrupole moment OEI in FCIDUMP format to ' + fname + '\n') # Frozen core + nuclear repulsion energy core.print_out('Writing frozen core + nuclear repulsion energy in FCIDUMP format to ' + fname + '\n') e_fzc = ints.get_frozen_core_energy() e_nuc = molecule.nuclear_repulsion_energy(wfn.get_dipole_field_strength()) intdump.write('{: 29.20E} {:4d} {:4d} {:4d} {:4d}\n'.format(e_fzc + e_nuc, 0, 0, 0, 0)) core.print_out('Done generating {} with integrals in FCIDUMP format.\n'.format(fname))
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") # 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) # reorder wavefuntions based on user input # apply a list of 2x2 rotation matrices to the orbitals in the form of [irrep, orbital1, orbital2, theta] # where an angle of 0 would do nothing and an angle of 90 would switch the two orbitals. # the indices of irreps and orbitals start from 0 reorder_orbitals = psi4.core.get_option("V2RDM_CASSCF", "MCSCF_ROTATE") for orbord in reorder_orbitals: if type(orbord) != list: raise psi4.p4util.PsiException( "Each element of the orbtial rotate list requires 4 arguements (irrep, orb1, orb2, theta)." ) if len(orbord) != 4: raise psi4.p4util.PsiException( "Each element of the orbtial rotate list requires 4 arguements (irrep, orb1, orb2, theta)." ) irrep, orb1, orb2, theta = orbord if irrep > ref_wfn.Ca().nirrep(): raise psi4.p4util.PsiException( "REORDER_ORBITALS: Expression %s irrep number is larger than the number of irreps" % (str(orbord))) if max(orb1, orb2) > ref_wfn.Ca().coldim()[irrep]: raise psi4.p4util.PsiException( "REORDER_ORBITALS: Expression %s orbital number exceeds number of orbitals in irrep" % (str(orbord))) theta = numpy.deg2rad(theta) x_a = ref_wfn.Ca().nph[irrep][:, orb1].copy() y_a = ref_wfn.Ca().nph[irrep][:, orb2].copy() xp_a = numpy.cos(theta) * x_a - numpy.sin(theta) * y_a yp_a = numpy.sin(theta) * x_a + numpy.cos(theta) * y_a ref_wfn.Ca().nph[irrep][:, orb1] = xp_a ref_wfn.Ca().nph[irrep][:, orb2] = yp_a x_b = ref_wfn.Ca().nph[irrep][:, orb1].copy() y_b = ref_wfn.Ca().nph[irrep][:, orb2].copy() xp_b = numpy.cos(theta) * x_b - numpy.sin(theta) * y_b yp_b = numpy.sin(theta) * x_b + numpy.cos(theta) * y_b ref_wfn.Ca().nph[irrep][:, orb1] = xp_b ref_wfn.Ca().nph[irrep][:, orb2] = yp_b returnvalue = psi4.core.plugin('v2rdm_casscf.so', ref_wfn) optstash.restore() return returnvalue
def run_efp_gamess(name, **kwargs): r"""Function encoding sequence of PSI module and plugin calls so that efp_gamess can be called via :py:func:`~driver.energy`. For post-scf plugins. >>> energy('efp_gamess') """ lowername = name.lower() kwargs = p4util.kwargs_lower(kwargs) # Your plugin's psi4 run sequence goes here psi4.core.set_local_option('MYPLUGIN', 'PRINT', 1) # Compute a SCF reference, a wavefunction is return which holds the molecule used, orbitals # Fock matrices, and more print('Attention! This SCF may be density-fitted.') ref_wfn = kwargs.get('ref_wfn', None) if ref_wfn is None: ref_wfn = psi4.driver.scf_helper(name, **kwargs) # Ensure IWL files have been written when not using DF/CD proc_util.check_iwl_file_from_scf_type( psi4.core.get_option('SCF', 'SCF_TYPE'), ref_wfn) # Call the Psi4 plugin # Please note that setting the reference wavefunction in this way is ONLY for plugins # This prints a bound python method print("\nPrinting ref_wfn.Fa") print(ref_wfn.Fa) # This defines a psi4.core.Matrix object and prints it print("\nPrinting np.asarray(ref_wfn.Fa())") print(np.asarray(ref_wfn.Fa())) #Farray=np.asarray(ref_wfn.Fa()) Farray = ref_wfn.Fa().to_array() print("\nPrinting Farray, which is np.asarray(ref_wfn.Fa())") print(Farray) print("\nPrinting Farray asarray") print(np.asarray(Farray)) # I think this does nothing different from the above Fa = ref_wfn.Fa() print("\nPrinting Fa=ref_wfn.Fa()") print(Fa) print("\nPrinting np.asarray(Fa)") print(np.asarray(Fa)) # This prints to the output the matrix values #Fa.print_out() # This actually changes Fa and the ref_wfn Fa value #Fa.set(0,0,0.0) #Fa.print_out() #ref_wfn.Fa=Fa # Tests my previous assertion about ref_wfn changes #Fa_zeroed=ref_wfn.Fa() #Fa_zeroed.print_out() # Change return name to the trans matrix I'm trying to send back #efp_gamess_wfn = psi4.core.plugin('efp_gamess.so', ref_wfn) psi4.core.set_local_option('efp_gamess', 'coleman', 0) trans_mat_c = psi4.core.plugin('efp_gamess.so', ref_wfn) print("\nPrinting C transformation matrix") print(trans_mat_c) print("\nPrinting C transformation matrix (as array)") print(np.asarray(trans_mat_c)) trans_mat_c.print_out() psi4.core.print_out("\nalright coleman H coming now") psi4.core.set_local_option('efp_gamess', 'coleman', 1) trans_mat_h = psi4.core.plugin('efp_gamess.so', ref_wfn) print("\nPrinting H transformation matrix") print(trans_mat_h) print("\nPrinting H transformation matrix (as array)") print(np.asarray(trans_mat_h)) trans_mat_h.print_out() # Define hdf5 file f = h5py.File("form.h5", "r") group = f["EFPcalc"] print("\nListing dataset in h5 file EFPcalc group") print(list(group.keys())) fock_dset = group['CONVERGED TOTAL FOCK MATRIX'] fock_np = np.array(fock_dset) print("\nGAMESS Fock matrix as numpy array") print(fock_np) mo_dset = group['MO_coeff'] mo_np = np.array(mo_dset) print("\nGAMESS MO coeficients") print(mo_np) print("\nPSI4 MO coefficients") print("\nTransforming MO coefficients") psi4_C = np.matmul(trans_mat_c, np.transpose(mo_np)) print("\nTransformed MO coefficients") print(psi4_C) # Test adding these together #print("Adding np.asarray(trans_mat_h)+np.asarray(trans_mat_c)\n") #test_sum=np.asarray(trans_mat_h)+np.asarray(trans_mat_c) #print(test_sum) #test_sum2=np.asarray(Fa)+np.asarray(trans_mat_c) #print(test_sum2) #test_sum.print_out() # Find out what trans_mat is (it's like the others) #print(trans_mat) # print actual values #trans_mat.print_out() # Change return to original ref_wfn, hopefully changed #return efp_gamess_wfn return ref_wfn
def run_oepdev(name, **kwargs): r"""Function encoding sequence of PSI module and plugin calls so that oepdev can be called via :py:func:`~driver.energy`. >>> energy('oepdev') """ # setup lowername = name.lower() kwargs = p4util.kwargs_lower(kwargs) #psi4.core.set_local_option('MYPLUGIN', 'PRINT', 1) # check if Cartesian basis sets are used msg = """\ OEPDev info: ------------ Currently only Cartesian basis sets are allowed to be used in OEPDev. Although spherical basis sets can be used for Psi4 integral factories, oepdev::ERI_3_1 electron repulsion integrals, that are needed for the generalized density fitting of OEP's, are implemented only for Cartesian GTO's, therefore using spherical harmonics is temporarily disabled in OEPDev. -> To continue, set PUREAM to False in your input file. <-""" assert (psi4.core.get_global_option("PUREAM") == False), msg ref_wfn = kwargs.get('ref_wfn', None) if ref_wfn is None: print(" [1] Computing HF/SCF for the dimer.") ref_wfn = psi4.driver.scf_helper(name, **kwargs) # grab molecule aggregate and all fragments (now only for dimer) print(" [2] Preparing basis sets for the monomers.") molecule = ref_wfn.molecule() # case when OEP build is requested if psi4.core.get_global_option("OEPDEV_TARGET").startswith("OEP") \ or psi4.core.get_global_option("OEPDEV_TARGET").startswith("DMAT") \ or (psi4.core.get_global_option("OEPDEV_TARGET") == "TEST" and psi4.core.get_global_option("OEPDEV_TEST_MODE") == "MONOMER"): basis_df_scf = psi4.core.BasisSet.build( molecule, "BASIS", psi4.core.get_global_option("DF_BASIS_SCF"), puream=ref_wfn.basisset().has_puream(), quiet=True) basis_df_oep = psi4.core.BasisSet.build( molecule, "BASIS", psi4.core.get_global_option("DF_BASIS_OEP"), puream=ref_wfn.basisset().has_puream(), quiet=True) if psi4.core.get_global_option("DF_BASIS_INT") == "": b_int = psi4.core.get_global_option("DF_BASIS_SCF") else: b_int = psi4.core.get_global_option("DF_BASIS_INT") basis_df_int = psi4.core.BasisSet.build( molecule, "BASIS", b_int, puream=ref_wfn.basisset().has_puream(), quiet=True) basis_guess = psi4.core.BasisSet.build( molecule, "BASIS", psi4.core.get_global_option("OEPDEV_BASIS_GUESS_SET"), puream=ref_wfn.basisset().has_puream(), quiet=True) #if (psi4.core.get_option("SCF", "GUESS") == "SAD"): # sad_basis_sets = psi4.core.BasisSet.build(molecule, "ORBITAL", psi4.core.get_global_option("BASIS"), # puream=ref_wfn.basisset().has_puream(), quiet=True, return_atomlist=True) # ref_wfn.set_sad_basissets(sad_basis_sets) # if ("DF" in psi4.core.get_option("SCF", "SAD_SCF_TYPE")): # sad_fitting_list = psi4.core.BasisSet.build(molecule, "DF_BASIS_SAD", psi4.core.get_option("SCF", "DF_BASIS_SAD"), # puream=True, return_atomlist=True) # ref_wfn.set_sad_fitting_basissets(sad_fitting_list) ref_wfn.set_basisset("BASIS_DF_OEP", basis_df_oep) ref_wfn.set_basisset("BASIS_DF_SCF", basis_df_scf) ref_wfn.set_basisset("BASIS_DF_INT", basis_df_int) ref_wfn.set_basisset("BASIS_GUESS", basis_guess) # case when task on wavefunction union can be requested elif(psi4.core.get_global_option("OEPDEV_TARGET") == "SOLVER") \ or (psi4.core.get_global_option("OEPDEV_TARGET") == "TEST" and psi4.core.get_global_option("OEPDEV_TEST_MODE") == "DIMER"): basis_df_scf = psi4.core.BasisSet.build( molecule, "BASIS", psi4.core.get_global_option("DF_BASIS_SCF"), puream=ref_wfn.basisset().has_puream(), quiet=True) molecule_A = molecule.extract_subsets(1) molecule_B = molecule.extract_subsets(2) # --- primary basis_A = psi4.core.BasisSet.build( molecule_A, "BASIS", psi4.core.get_global_option("BASIS"), puream=ref_wfn.basisset().has_puream(), quiet=True) basis_B = psi4.core.BasisSet.build( molecule_B, "BASIS", psi4.core.get_global_option("BASIS"), puream=ref_wfn.basisset().has_puream(), quiet=True) # --- auxiliary (DF-SCF) basis_df_scf_A = psi4.core.BasisSet.build( molecule_A, "BASIS", psi4.core.get_global_option("DF_BASIS_SCF"), puream=ref_wfn.basisset().has_puream(), quiet=True) basis_df_scf_B = psi4.core.BasisSet.build( molecule_B, "BASIS", psi4.core.get_global_option("DF_BASIS_SCF"), puream=ref_wfn.basisset().has_puream(), quiet=True) # --- auxiliary (OEP) opt_basis_df_oep_A = psi4.core.get_global_option("DF_BASIS_OEP_A") opt_basis_df_oep_B = psi4.core.get_global_option("DF_BASIS_OEP_B") opt_basis_df_oep = psi4.core.get_global_option("DF_BASIS_OEP") if not opt_basis_df_oep_A: opt_basis_df_oep_A = opt_basis_df_oep if not opt_basis_df_oep_B: opt_basis_df_oep_B = opt_basis_df_oep basis_df_oep_A = psi4.core.BasisSet.build( molecule_A, "BASIS", opt_basis_df_oep_A, puream=ref_wfn.basisset().has_puream(), quiet=True) basis_df_oep_B = psi4.core.BasisSet.build( molecule_B, "BASIS", opt_basis_df_oep_B, puream=ref_wfn.basisset().has_puream(), quiet=True) # --- intermediate (OEP) if psi4.core.get_global_option("DF_BASIS_INT") == "": b_int = psi4.core.get_global_option("DF_BASIS_SCF") else: b_int = psi4.core.get_global_option("DF_BASIS_INT") basis_int_oep_A = psi4.core.BasisSet.build( molecule_A, "BASIS", b_int, puream=ref_wfn.basisset().has_puream(), quiet=True) basis_int_oep_B = psi4.core.BasisSet.build( molecule_B, "BASIS", b_int, puream=ref_wfn.basisset().has_puream(), quiet=True) # --- guess (OEP) basis_guess_A = psi4.core.BasisSet.build( molecule_A, "BASIS", psi4.core.get_global_option("OEPDEV_BASIS_GUESS_SET"), puream=ref_wfn.basisset().has_puream(), quiet=True) basis_guess_B = psi4.core.BasisSet.build( molecule_B, "BASIS", psi4.core.get_global_option("OEPDEV_BASIS_GUESS_SET"), puream=ref_wfn.basisset().has_puream(), quiet=True) # --- SAD Guess (Psi4) #if (psi4.core.get_option("SCF", "GUESS") == "SAD"): # sad_basis_sets_A = psi4.core.BasisSet.build(molecule_A, "ORBITAL", psi4.core.get_global_option("BASIS"), # puream=ref_wfn.basisset().has_puream(), quiet=True, return_atomlist=True) # sad_basis_sets_B = psi4.core.BasisSet.build(molecule_B, "ORBITAL", psi4.core.get_global_option("BASIS"), # puream=ref_wfn.basisset().has_puream(), quiet=True, return_atomlist=True) # ref_wfn.set_sad_basissets(sad_basis_sets_A+sad_basis_sets_B) # if ("DF" in psi4.core.get_option("SCF", "SAD_SCF_TYPE")): # sad_fit_list_A = psi4.core.BasisSet.build(molecule_A, "DF_BASIS_SAD", psi4.core.get_option("SCF", "DF_BASIS_SAD"), # puream=True, return_atomlist=True) # sad_fit_list_B = psi4.core.BasisSet.build(molecule_B, "DF_BASIS_SAD", psi4.core.get_option("SCF", "DF_BASIS_SAD"), # puream=True, return_atomlist=True) # ref_wfn.set_sad_fitting_basissets(sad_fit_list_A+sad_fit_list_B) ref_wfn.set_basisset("BASIS_1", basis_A) ref_wfn.set_basisset("BASIS_2", basis_B) ref_wfn.set_basisset("BASIS_DF_SCF_1", basis_df_scf_A) ref_wfn.set_basisset("BASIS_DF_SCF_2", basis_df_scf_B) ref_wfn.set_basisset("BASIS_DF_OEP_1", basis_df_oep_A) ref_wfn.set_basisset("BASIS_DF_OEP_2", basis_df_oep_B) ref_wfn.set_basisset("BASIS_INT_OEP_1", basis_int_oep_A) ref_wfn.set_basisset("BASIS_INT_OEP_2", basis_int_oep_B) ref_wfn.set_basisset("BASIS_GUESS_1", basis_guess_A) ref_wfn.set_basisset("BASIS_GUESS_2", basis_guess_B) ref_wfn.set_basisset("BASIS_DF_SCF", basis_df_scf) # Ensure IWL files have been written when not using DF/CD proc_util.check_iwl_file_from_scf_type( psi4.core.get_option('SCF', 'SCF_TYPE'), ref_wfn) # Call the Psi4 plugin print(" [3] Running OEPDev plugin.") oepdev_wfn = psi4.core.plugin('oepdev.so', ref_wfn) return oepdev_wfn